LCOV - code coverage report
Current view: top level - gcc/c-family - c-gimplify.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 88.5 % 477 422
Test Date: 2025-03-08 13:07:09 Functions: 88.0 % 25 22
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Tree lowering pass.  This pass gimplifies the tree representation built
       2                 :             :    by the C-based front ends.  The structure of gimplified, or
       3                 :             :    language-independent, trees is dictated by the grammar described in this
       4                 :             :    file.
       5                 :             :    Copyright (C) 2002-2025 Free Software Foundation, Inc.
       6                 :             :    Lowering of expressions contributed by Sebastian Pop <s.pop@laposte.net>
       7                 :             :    Re-written to support lowering of whole function trees, documentation
       8                 :             :    and miscellaneous cleanups by Diego Novillo <dnovillo@redhat.com>
       9                 :             : 
      10                 :             : This file is part of GCC.
      11                 :             : 
      12                 :             : GCC is free software; you can redistribute it and/or modify it under
      13                 :             : the terms of the GNU General Public License as published by the Free
      14                 :             : Software Foundation; either version 3, or (at your option) any later
      15                 :             : version.
      16                 :             : 
      17                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      18                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      19                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      20                 :             : for more details.
      21                 :             : 
      22                 :             : You should have received a copy of the GNU General Public License
      23                 :             : along with GCC; see the file COPYING3.  If not see
      24                 :             : <http://www.gnu.org/licenses/>.  */
      25                 :             : 
      26                 :             : #include "config.h"
      27                 :             : #include "system.h"
      28                 :             : #include "coretypes.h"
      29                 :             : #include "tm.h"
      30                 :             : #include "function.h"
      31                 :             : #include "basic-block.h"
      32                 :             : #include "tree.h"
      33                 :             : #include "tree-iterator.h"
      34                 :             : #include "predict.h"
      35                 :             : #include "gimple.h"
      36                 :             : #include "cgraph.h"
      37                 :             : #include "c-pretty-print.h"
      38                 :             : #include "gimplify.h"
      39                 :             : #include "langhooks.h"
      40                 :             : #include "dumpfile.h"
      41                 :             : #include "c-ubsan.h"
      42                 :             : #include "tree-nested.h"
      43                 :             : #include "context.h"
      44                 :             : #include "tree-pass.h"
      45                 :             : #include "internal-fn.h"
      46                 :             : #include "omp-general.h"
      47                 :             : 
      48                 :             : /*  The gimplification pass converts the language-dependent trees
      49                 :             :     (ld-trees) emitted by the parser into language-independent trees
      50                 :             :     (li-trees) that are the target of SSA analysis and transformations.
      51                 :             : 
      52                 :             :     Language-independent trees are based on the SIMPLE intermediate
      53                 :             :     representation used in the McCAT compiler framework:
      54                 :             : 
      55                 :             :     "Designing the McCAT Compiler Based on a Family of Structured
      56                 :             :     Intermediate Representations,"
      57                 :             :     L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
      58                 :             :     Proceedings of the 5th International Workshop on Languages and
      59                 :             :     Compilers for Parallel Computing, no. 757 in Lecture Notes in
      60                 :             :     Computer Science, New Haven, Connecticut, pp. 406-420,
      61                 :             :     Springer-Verlag, August 3-5, 1992.
      62                 :             : 
      63                 :             :     http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
      64                 :             : 
      65                 :             :     Basically, we walk down gimplifying the nodes that we encounter.  As we
      66                 :             :     walk back up, we check that they fit our constraints, and copy them
      67                 :             :     into temporaries if not.  */
      68                 :             : 
      69                 :             : /* Callback for c_genericize.  */
      70                 :             : 
      71                 :             : static tree
      72                 :     1282932 : ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
      73                 :             : {
      74                 :     1282932 :   hash_set<tree> *pset = (hash_set<tree> *) data;
      75                 :             : 
      76                 :     1282932 :   if (TREE_CODE (*tp) == BIND_EXPR)
      77                 :             :     {
      78                 :             :       /* Since walk_tree doesn't call the callback function on the decls
      79                 :             :          in BIND_EXPR_VARS, we have to walk them manually, so we can avoid
      80                 :             :          instrumenting DECL_INITIAL of TREE_STATIC vars.  */
      81                 :       65884 :       *walk_subtrees = 0;
      82                 :       81521 :       for (tree decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
      83                 :             :         {
      84                 :       15637 :           if (TREE_STATIC (decl))
      85                 :         138 :             continue;
      86                 :       15499 :           walk_tree (&DECL_INITIAL (decl), ubsan_walk_array_refs_r, pset,
      87                 :             :                      pset);
      88                 :       15499 :           walk_tree (&DECL_SIZE (decl), ubsan_walk_array_refs_r, pset, pset);
      89                 :       15499 :           walk_tree (&DECL_SIZE_UNIT (decl), ubsan_walk_array_refs_r, pset,
      90                 :             :                      pset);
      91                 :             :         }
      92                 :       65884 :       walk_tree (&BIND_EXPR_BODY (*tp), ubsan_walk_array_refs_r, pset, pset);
      93                 :             :     }
      94                 :     1217048 :   else if (TREE_CODE (*tp) == ADDR_EXPR
      95                 :     1217048 :            && TREE_CODE (TREE_OPERAND (*tp, 0)) == ARRAY_REF)
      96                 :             :     {
      97                 :         257 :       ubsan_maybe_instrument_array_ref (&TREE_OPERAND (*tp, 0), true);
      98                 :             :       /* Make sure ubsan_maybe_instrument_array_ref is not called again
      99                 :             :          on the ARRAY_REF, the above call might not instrument anything
     100                 :             :          as the index might be constant or masked, so ensure it is not
     101                 :             :          walked again and walk its subtrees manually.  */
     102                 :         257 :       tree aref = TREE_OPERAND (*tp, 0);
     103                 :         257 :       pset->add (aref);
     104                 :         257 :       *walk_subtrees = 0;
     105                 :         257 :       walk_tree (&TREE_OPERAND (aref, 0), ubsan_walk_array_refs_r, pset, pset);
     106                 :         257 :       walk_tree (&TREE_OPERAND (aref, 1), ubsan_walk_array_refs_r, pset, pset);
     107                 :         257 :       walk_tree (&TREE_OPERAND (aref, 2), ubsan_walk_array_refs_r, pset, pset);
     108                 :         257 :       walk_tree (&TREE_OPERAND (aref, 3), ubsan_walk_array_refs_r, pset, pset);
     109                 :             :     }
     110                 :     1216791 :   else if (TREE_CODE (*tp) == ARRAY_REF)
     111                 :        3983 :     ubsan_maybe_instrument_array_ref (tp, false);
     112                 :     1212808 :   else if (TREE_CODE (*tp) == MODIFY_EXPR)
     113                 :             :     {
     114                 :             :       /* Since r7-1900, we gimplify RHS before LHS.  Consider
     115                 :             :            a[b] |= c;
     116                 :             :          wherein we can have a single shared tree a[b] in both LHS and RHS.
     117                 :             :          If we only instrument the LHS and the access is invalid, the program
     118                 :             :          could crash before emitting a UBSan error.  So instrument the RHS
     119                 :             :          first.  */
     120                 :       67664 :       *walk_subtrees = 0;
     121                 :       67664 :       walk_tree (&TREE_OPERAND (*tp, 1), ubsan_walk_array_refs_r, pset, pset);
     122                 :       67664 :       walk_tree (&TREE_OPERAND (*tp, 0), ubsan_walk_array_refs_r, pset, pset);
     123                 :             :     }
     124                 :     1282932 :   return NULL_TREE;
     125                 :             : }
     126                 :             : 
     127                 :             : /* Gimplification of statement trees.  */
     128                 :             : 
     129                 :             : /* Local declarations.  */
     130                 :             : 
     131                 :             : enum bc_t { bc_break = 0, bc_continue = 1 };
     132                 :             : 
     133                 :             : /* Stack of labels which are targets for "break" or "continue",
     134                 :             :    linked through TREE_CHAIN.  */
     135                 :             : static tree bc_label[2];
     136                 :             : 
     137                 :             : /* Hash map from loop/switch names (identified by LABEL_DECL) to
     138                 :             :    corresponding break and (if any) continue labels.  */
     139                 :             : static bc_hash_map_t *bc_hash_map;
     140                 :             : 
     141                 :             : /* Begin a scope which can be exited by a break or continue statement.  BC
     142                 :             :    indicates which.
     143                 :             : 
     144                 :             :    Just creates a label with location LOCATION and pushes it into the current
     145                 :             :    context.  */
     146                 :             : 
     147                 :             : static tree
     148                 :     6926791 : begin_bc_block (enum bc_t bc, location_t location)
     149                 :             : {
     150                 :     6926791 :   tree label = create_artificial_label (location);
     151                 :     6926791 :   DECL_CHAIN (label) = bc_label[bc];
     152                 :     6926791 :   bc_label[bc] = label;
     153                 :     6926791 :   if (bc == bc_break)
     154                 :     3596655 :     LABEL_DECL_BREAK (label) = true;
     155                 :             :   else
     156                 :     3330136 :     LABEL_DECL_CONTINUE (label) = true;
     157                 :     6926791 :   return label;
     158                 :             : }
     159                 :             : 
     160                 :             : /* Finish a scope which can be exited by a break or continue statement.
     161                 :             :    LABEL was returned from the most recent call to begin_bc_block.  BLOCK is
     162                 :             :    an expression for the contents of the scope.
     163                 :             : 
     164                 :             :    If we saw a break (or continue) in the scope, append a LABEL_EXPR to
     165                 :             :    BLOCK.  Otherwise, just forget the label.  */
     166                 :             : 
     167                 :             : static void
     168                 :     6926791 : finish_bc_block (tree *block, enum bc_t bc, tree label)
     169                 :             : {
     170                 :     6926791 :   gcc_assert (label == bc_label[bc]);
     171                 :             : 
     172                 :     6926791 :   if (TREE_USED (label))
     173                 :     2756445 :     append_to_statement_list (build1 (LABEL_EXPR, void_type_node, label),
     174                 :             :                               block);
     175                 :             : 
     176                 :     6926791 :   bc_label[bc] = DECL_CHAIN (label);
     177                 :     6926791 :   DECL_CHAIN (label) = NULL_TREE;
     178                 :     6926791 : }
     179                 :             : 
     180                 :             : /* For named loop or switch with NAME, remember corresponding break
     181                 :             :    label BLAB and continue label CLAB.  */
     182                 :             : 
     183                 :             : static void
     184                 :          46 : note_named_bc (tree name, tree blab, tree clab)
     185                 :             : {
     186                 :          46 :   if (bc_hash_map == NULL)
     187                 :          14 :     bc_hash_map = new bc_hash_map_t (32);
     188                 :          46 :   bc_hash_map->put (name, std::make_pair (blab, clab));
     189                 :          46 : }
     190                 :             : 
     191                 :             : /* Remove NAME from the map after processing body of the loop or
     192                 :             :    switch.  */
     193                 :             : 
     194                 :             : static void
     195                 :          46 : release_named_bc (tree name)
     196                 :             : {
     197                 :           0 :   bc_hash_map->remove (name);
     198                 :           0 : }
     199                 :             : 
     200                 :             : /* Allow saving and restoring break/continue state.  */
     201                 :             : 
     202                 :             : void
     203                 :    76236126 : save_bc_state (bc_state_t *state)
     204                 :             : {
     205                 :    76236126 :   state->bc_label[bc_break] = bc_label[bc_break];
     206                 :    76236126 :   state->bc_label[bc_continue] = bc_label[bc_continue];
     207                 :    76236126 :   state->bc_hash_map = bc_hash_map;
     208                 :    76236126 :   bc_label[bc_break] = NULL_TREE;
     209                 :    76236126 :   bc_label[bc_continue] = NULL_TREE;
     210                 :    76236126 :   bc_hash_map = NULL;
     211                 :    76236126 : }
     212                 :             : 
     213                 :             : void
     214                 :    76236126 : restore_bc_state (bc_state_t *state)
     215                 :             : {
     216                 :    76236126 :   gcc_assert (bc_label[bc_break] == NULL);
     217                 :    76236126 :   gcc_assert (bc_label[bc_continue] == NULL);
     218                 :    76236126 :   gcc_assert (bc_hash_map == NULL);
     219                 :    76236126 :   bc_label[bc_break] = state->bc_label[bc_break];
     220                 :    76236126 :   bc_label[bc_continue] = state->bc_label[bc_continue];
     221                 :    76236126 :   bc_hash_map = state->bc_hash_map;
     222                 :    76236126 : }
     223                 :             : 
     224                 :             : /* Get the LABEL_EXPR to represent a break or continue statement
     225                 :             :    in the current block scope.  BC indicates which.  */
     226                 :             : 
     227                 :             : static tree
     228                 :     3834980 : get_bc_label (enum bc_t bc)
     229                 :             : {
     230                 :     3834980 :   tree label = bc_label[bc];
     231                 :     3834980 :   gcc_assert (label);
     232                 :             : 
     233                 :             :   /* Mark the label used for finish_bc_block.  */
     234                 :     3834980 :   TREE_USED (label) = 1;
     235                 :     3834980 :   return label;
     236                 :             : }
     237                 :             : 
     238                 :             : /* Return the location from EXPR, or OR_LOC if the former is unknown.  */
     239                 :             : 
     240                 :             : location_t
     241                 :     7886606 : expr_loc_or_loc (const_tree expr, location_t or_loc)
     242                 :             : {
     243                 :     7886606 :   tree t = CONST_CAST_TREE (expr);
     244                 :     7886606 :   location_t loc = UNKNOWN_LOCATION;
     245                 :     7886606 :   if (t)
     246                 :     6037554 :     loc = EXPR_LOCATION (t);
     247                 :     4913159 :   if (loc == UNKNOWN_LOCATION)
     248                 :     4212335 :     loc = or_loc;
     249                 :     7886606 :   return loc;
     250                 :             : }
     251                 :             : 
     252                 :             : /* Build a generic representation of one of the C loop forms.  COND is the
     253                 :             :    loop condition or NULL_TREE.  BODY is the (possibly compound) statement
     254                 :             :    controlled by the loop.  INCR is the increment expression of a for-loop,
     255                 :             :    or NULL_TREE.  COND_IS_FIRST indicates whether the condition is
     256                 :             :    evaluated before the loop body as in while and for loops, or after the
     257                 :             :    loop body as in do-while loops.  COND_PREP and COND_CLEANUP are used
     258                 :             :    for C++ for/while loops with variable declaration as condition.  COND_PREP
     259                 :             :    is a BIND_EXPR with the declaration and initialization of the condition
     260                 :             :    variable, into which COND, BODY, continue label if needed and INCR if
     261                 :             :    non-NULL should be appended, and COND_CLEANUP is number of nested
     262                 :             :    CLEANUP_STMT -> TRY_FINALLY_EXPR statements at the end.  If non-NULL,
     263                 :             :    COND, BODY, continue label if needed and INCR if non-NULL should be
     264                 :             :    appended to the body of the COND_CLEANUP's nested TRY_FINALLY_EXPR.  */
     265                 :             : 
     266                 :             : static void
     267                 :     3287831 : genericize_c_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
     268                 :             :                    tree incr, tree name, tree cond_prep, tree cond_cleanup,
     269                 :             :                    bool cond_is_first, int *walk_subtrees, void *data,
     270                 :             :                    walk_tree_fn func, walk_tree_lh lh)
     271                 :             : {
     272                 :     3287831 :   tree blab, clab;
     273                 :     3287831 :   tree entry = NULL, exit = NULL, t;
     274                 :     3287831 :   tree stmt_list = NULL, outer_stmt_list = NULL_TREE, *stmt_list_p = NULL;
     275                 :     3287831 :   location_t cond_locus = expr_loc_or_loc (cond, start_locus);
     276                 :     3287831 :   location_t incr_locus = expr_loc_or_loc (incr, start_locus);
     277                 :             : 
     278                 :     3287831 :   protected_set_expr_location_if_unset (incr, start_locus);
     279                 :             : 
     280                 :     3287831 :   walk_tree_1 (&cond_prep, func, data, NULL, lh);
     281                 :     3287831 :   walk_tree_1 (&cond, func, data, NULL, lh);
     282                 :     3287831 :   walk_tree_1 (&incr, func, data, NULL, lh);
     283                 :             : 
     284                 :     3287831 :   blab = begin_bc_block (bc_break, start_locus);
     285                 :     3287831 :   clab = begin_bc_block (bc_continue, start_locus);
     286                 :     3287831 :   if (name)
     287                 :          35 :     note_named_bc (name, blab, clab);
     288                 :             : 
     289                 :     3287831 :   walk_tree_1 (&body, func, data, NULL, lh);
     290                 :     3287831 :   *walk_subtrees = 0;
     291                 :             : 
     292                 :     3287831 :   if (name)
     293                 :          35 :     release_named_bc (name);
     294                 :             : 
     295                 :     3287831 :   if (cond_prep)
     296                 :             :     {
     297                 :             :       /* The C++ cases of
     298                 :             :          while (A x = 42) body;
     299                 :             :          for (; A x = 42; expr) body;
     300                 :             :          This should be expanded into:
     301                 :             : 
     302                 :             :          top:
     303                 :             :          COND_PREP
     304                 :             : 
     305                 :             :          with either
     306                 :             : 
     307                 :             :          if (COND); else break;
     308                 :             :          BODY;
     309                 :             :          cont:
     310                 :             :          EXPR;
     311                 :             :          goto top;
     312                 :             : 
     313                 :             :          appended into COND_PREP body or body of some TRY_FINALLY_EXPRs
     314                 :             :          at the end of COND_PREP.  */
     315                 :        9768 :       gcc_assert (cond_is_first && TREE_CODE (cond_prep) == BIND_EXPR);
     316                 :        9768 :       tree top = build1 (LABEL_EXPR, void_type_node,
     317                 :             :                          create_artificial_label (start_locus));
     318                 :        9768 :       exit = build1 (GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL (top));
     319                 :        9768 :       append_to_statement_list (top, &outer_stmt_list);
     320                 :        9768 :       append_to_statement_list (cond_prep, &outer_stmt_list);
     321                 :        9768 :       stmt_list_p = &BIND_EXPR_BODY (cond_prep);
     322                 :        9768 :       if (cond_cleanup)
     323                 :         206 :         for (unsigned depth = tree_to_uhwi (cond_cleanup); depth; --depth)
     324                 :             :           {
     325                 :         109 :             t = tsi_stmt (tsi_last (*stmt_list_p));
     326                 :         109 :             gcc_assert (TREE_CODE (t) == TRY_FINALLY_EXPR);
     327                 :         109 :             stmt_list_p = &TREE_OPERAND (t, 0);
     328                 :             :           }
     329                 :        9768 :       stmt_list = *stmt_list_p;
     330                 :        9768 :       *stmt_list_p = NULL_TREE;
     331                 :        9768 :       tree after_cond = create_artificial_label (cond_locus);
     332                 :        9768 :       tree goto_after_cond = build1 (GOTO_EXPR, void_type_node, after_cond);
     333                 :        9768 :       t = build1 (GOTO_EXPR, void_type_node, get_bc_label (bc_break));
     334                 :        9768 :       t = fold_build3_loc (cond_locus, COND_EXPR, void_type_node, cond,
     335                 :             :                            goto_after_cond, t);
     336                 :        9768 :       append_to_statement_list (t, &stmt_list);
     337                 :        9768 :       t = build1 (LABEL_EXPR, void_type_node, after_cond);
     338                 :        9768 :       append_to_statement_list (t, &stmt_list);
     339                 :             :     }
     340                 :     3278063 :   else if (cond && integer_zerop (cond))
     341                 :             :     {
     342                 :             :       /* If condition is zero don't generate a loop construct.  */
     343                 :     1076068 :       if (cond_is_first)
     344                 :             :         {
     345                 :         196 :           t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
     346                 :             :                           get_bc_label (bc_break));
     347                 :         196 :           append_to_statement_list (t, &stmt_list);
     348                 :             :         }
     349                 :             :     }
     350                 :             :   else
     351                 :             :     {
     352                 :             :       /* Expand to gotos.  */
     353                 :     2201995 :       tree top = build1 (LABEL_EXPR, void_type_node,
     354                 :             :                          create_artificial_label (start_locus));
     355                 :             : 
     356                 :             :       /* If we have an exit condition, then we build an IF with gotos either
     357                 :             :          out of the loop, or to the top of it.  If there's no exit condition,
     358                 :             :          then we just build a jump back to the top.  */
     359                 :     2201995 :       exit = build1 (GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL (top));
     360                 :             : 
     361                 :     2201995 :       if (cond && !integer_nonzerop (cond))
     362                 :             :         {
     363                 :             :           /* Canonicalize the loop condition to the end.  This means
     364                 :             :              generating a branch to the loop condition.  Reuse the
     365                 :             :              continue label, if there is no incr expression.  */
     366                 :     2094784 :           if (cond_is_first)
     367                 :             :             {
     368                 :     1940930 :               if (incr)
     369                 :             :                 {
     370                 :     1496365 :                   entry = build1 (LABEL_EXPR, void_type_node,
     371                 :             :                                   create_artificial_label (start_locus));
     372                 :     2992730 :                   t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
     373                 :     1496365 :                                   LABEL_EXPR_LABEL (entry));
     374                 :             :                 }
     375                 :             :               else
     376                 :      444565 :                 t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
     377                 :             :                                 get_bc_label (bc_continue));
     378                 :     1940930 :               append_to_statement_list (t, &stmt_list);
     379                 :             :             }
     380                 :             : 
     381                 :     2094784 :           t = build1 (GOTO_EXPR, void_type_node, get_bc_label (bc_break));
     382                 :     2094784 :           exit = fold_build3_loc (cond_locus,
     383                 :             :                                   COND_EXPR, void_type_node, cond, exit, t);
     384                 :             :         }
     385                 :             :       else
     386                 :             :         {
     387                 :             :           /* For the backward-goto's location of an unconditional loop
     388                 :             :              use the beginning of the body, or, if there is none, the
     389                 :             :              top of the loop.  */
     390                 :      107211 :           location_t loc = expr_loc_or_loc (expr_first (body),
     391                 :             :                                             start_locus);
     392                 :      107211 :           SET_EXPR_LOCATION (exit, loc);
     393                 :             :         }
     394                 :     2201995 :       append_to_statement_list (top, &stmt_list);
     395                 :             :     }
     396                 :             : 
     397                 :     3287831 :   append_to_statement_list (body, &stmt_list);
     398                 :     3287831 :   if (c_dialect_cxx ()
     399                 :     2828176 :       && stmt_list
     400                 :     2826279 :       && TREE_CODE (stmt_list) == STATEMENT_LIST)
     401                 :             :     {
     402                 :     2826279 :       tree_stmt_iterator tsi = tsi_last (stmt_list);
     403                 :     2826279 :       if (!tsi_end_p (tsi))
     404                 :             :         {
     405                 :     2826279 :           tree t = *tsi;
     406                 :     2826279 :           while (TREE_CODE (t) == CLEANUP_POINT_EXPR
     407                 :             :                  || TREE_CODE (t) == EXPR_STMT
     408                 :     5072473 :                  || CONVERT_EXPR_CODE_P (TREE_CODE (t)))
     409                 :     2246194 :             t = TREE_OPERAND (t, 0);
     410                 :             :           /* For C++, if iteration statement body ends with fallthrough
     411                 :             :              statement, mark it such that we diagnose it even if next
     412                 :             :              statement would be labeled statement with case/default label.  */
     413                 :     2826279 :           if (TREE_CODE (t) == CALL_EXPR
     414                 :      104911 :               && !CALL_EXPR_FN (t)
     415                 :     2826291 :               && CALL_EXPR_IFN (t) == IFN_FALLTHROUGH)
     416                 :          12 :             TREE_NOTHROW (t) = 1;
     417                 :             :         }
     418                 :             :     }
     419                 :     3287831 :   finish_bc_block (&stmt_list, bc_continue, clab);
     420                 :     3287831 :   if (incr)
     421                 :             :     {
     422                 :     1498972 :       if (MAY_HAVE_DEBUG_MARKER_STMTS && incr_locus != UNKNOWN_LOCATION)
     423                 :             :         {
     424                 :     1203733 :           tree d = build0 (DEBUG_BEGIN_STMT, void_type_node);
     425                 :     1203733 :           SET_EXPR_LOCATION (d, expr_loc_or_loc (incr, start_locus));
     426                 :     1203733 :           append_to_statement_list (d, &stmt_list);
     427                 :             :         }
     428                 :     1498972 :       append_to_statement_list (incr, &stmt_list);
     429                 :             :     }
     430                 :     3287831 :   append_to_statement_list (entry, &stmt_list);
     431                 :             : 
     432                 :     3287831 :   if (MAY_HAVE_DEBUG_MARKER_STMTS && cond_locus != UNKNOWN_LOCATION)
     433                 :             :     {
     434                 :     2774989 :       tree d = build0 (DEBUG_BEGIN_STMT, void_type_node);
     435                 :     2774989 :       SET_EXPR_LOCATION (d, cond_locus);
     436                 :     2774989 :       append_to_statement_list (d, &stmt_list);
     437                 :             :     }
     438                 :     3287831 :   append_to_statement_list (exit, &stmt_list);
     439                 :     3287831 :   if (stmt_list_p)
     440                 :             :     {
     441                 :        9768 :       *stmt_list_p = stmt_list;
     442                 :        9768 :       stmt_list = outer_stmt_list;
     443                 :             :     }
     444                 :     3287831 :   finish_bc_block (&stmt_list, bc_break, blab);
     445                 :     3287831 :   if (!stmt_list)
     446                 :        3585 :     stmt_list = build_empty_stmt (start_locus);
     447                 :             : 
     448                 :     3287831 :   *stmt_p = stmt_list;
     449                 :     3287831 : }
     450                 :             : 
     451                 :             : /* Genericize a FOR_STMT node *STMT_P.  */
     452                 :             : 
     453                 :             : static void
     454                 :     1561772 : genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data,
     455                 :             :                      walk_tree_fn func, walk_tree_lh lh)
     456                 :             : {
     457                 :     1561772 :   tree stmt = *stmt_p;
     458                 :     1561772 :   tree expr = NULL;
     459                 :     1561772 :   tree loop;
     460                 :     1561772 :   tree init = FOR_INIT_STMT (stmt);
     461                 :             : 
     462                 :     1561772 :   if (init)
     463                 :             :     {
     464                 :           0 :       walk_tree_1 (&init, func, data, NULL, lh);
     465                 :           0 :       append_to_statement_list (init, &expr);
     466                 :             :     }
     467                 :             : 
     468                 :     3123544 :   genericize_c_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt),
     469                 :     1561772 :                      FOR_BODY (stmt), FOR_EXPR (stmt), FOR_NAME (stmt),
     470                 :     1561772 :                      FOR_COND_PREP (stmt), FOR_COND_CLEANUP (stmt), 1,
     471                 :             :                      walk_subtrees, data, func, lh);
     472                 :     1561772 :   append_to_statement_list (loop, &expr);
     473                 :     1561772 :   if (expr == NULL_TREE)
     474                 :           0 :     expr = loop;
     475                 :     1561772 :   *stmt_p = expr;
     476                 :     1561772 : }
     477                 :             : 
     478                 :             : /* Genericize a WHILE_STMT node *STMT_P.  */
     479                 :             : 
     480                 :             : static void
     481                 :      495937 : genericize_while_stmt (tree *stmt_p, int *walk_subtrees, void *data,
     482                 :             :                        walk_tree_fn func, walk_tree_lh lh)
     483                 :             : {
     484                 :      495937 :   tree stmt = *stmt_p;
     485                 :      991874 :   genericize_c_loop (stmt_p, EXPR_LOCATION (stmt), WHILE_COND (stmt),
     486                 :      495937 :                      WHILE_BODY (stmt), NULL_TREE, WHILE_NAME (stmt),
     487                 :      495937 :                      WHILE_COND_PREP (stmt), WHILE_COND_CLEANUP (stmt), 1,
     488                 :             :                      walk_subtrees, data, func, lh);
     489                 :      495937 : }
     490                 :             : 
     491                 :             : /* Genericize a DO_STMT node *STMT_P.  */
     492                 :             : 
     493                 :             : static void
     494                 :     1230122 : genericize_do_stmt (tree *stmt_p, int *walk_subtrees, void *data,
     495                 :             :                     walk_tree_fn func, walk_tree_lh lh)
     496                 :             : {
     497                 :     1230122 :   tree stmt = *stmt_p;
     498                 :     2460244 :   genericize_c_loop (stmt_p, EXPR_LOCATION (stmt), DO_COND (stmt),
     499                 :     1230122 :                      DO_BODY (stmt), NULL_TREE, DO_NAME (stmt),
     500                 :             :                      NULL_TREE, NULL_TREE, 0, walk_subtrees, data, func, lh);
     501                 :     1230122 : }
     502                 :             : 
     503                 :             : /* Genericize a SWITCH_STMT node *STMT_P by turning it into a SWITCH_EXPR.  */
     504                 :             : 
     505                 :             : static void
     506                 :      308824 : genericize_switch_stmt (tree *stmt_p, int *walk_subtrees, void *data,
     507                 :             :                         walk_tree_fn func, walk_tree_lh lh)
     508                 :             : {
     509                 :      308824 :   tree stmt = *stmt_p;
     510                 :      308824 :   tree blab, body, cond, type;
     511                 :      308824 :   location_t stmt_locus = EXPR_LOCATION (stmt);
     512                 :             : 
     513                 :      308824 :   body = SWITCH_STMT_BODY (stmt);
     514                 :      308824 :   if (!body)
     515                 :           0 :     body = build_empty_stmt (stmt_locus);
     516                 :      308824 :   cond = SWITCH_STMT_COND (stmt);
     517                 :      308824 :   type = SWITCH_STMT_TYPE (stmt);
     518                 :             : 
     519                 :      308824 :   walk_tree_1 (&cond, func, data, NULL, lh);
     520                 :             : 
     521                 :      308824 :   blab = begin_bc_block (bc_break, stmt_locus);
     522                 :      308824 :   if (SWITCH_STMT_NAME (stmt))
     523                 :          11 :     note_named_bc (SWITCH_STMT_NAME (stmt), blab, NULL_TREE);
     524                 :             : 
     525                 :      308824 :   walk_tree_1 (&body, func, data, NULL, lh);
     526                 :             : 
     527                 :      308824 :   if (SWITCH_STMT_NAME (stmt))
     528                 :          11 :     release_named_bc (SWITCH_STMT_NAME (stmt));
     529                 :             : 
     530                 :      308824 :   walk_tree_1 (&type, func, data, NULL, lh);
     531                 :      308824 :   *walk_subtrees = 0;
     532                 :             : 
     533                 :      308824 :   if (TREE_USED (blab))
     534                 :      150094 :     SWITCH_BREAK_LABEL_P (blab) = 1;
     535                 :      308824 :   finish_bc_block (&body, bc_break, blab);
     536                 :      308824 :   *stmt_p = build2_loc (stmt_locus, SWITCH_EXPR, type, cond, body);
     537                 :      308824 :   SWITCH_ALL_CASES_P (*stmt_p) = SWITCH_STMT_ALL_CASES_P (stmt);
     538                 :      308824 :   gcc_checking_assert (!SWITCH_STMT_NO_BREAK_P (stmt)
     539                 :             :                        || !TREE_USED (blab));
     540                 :      308824 : }
     541                 :             : 
     542                 :             : /* Genericize a CONTINUE_STMT node *STMT_P.  */
     543                 :             : 
     544                 :             : static void
     545                 :       16705 : genericize_continue_stmt (tree *stmt_p)
     546                 :             : {
     547                 :       16705 :   tree stmt_list = NULL;
     548                 :       16705 :   tree pred = build_predict_expr (PRED_CONTINUE, NOT_TAKEN);
     549                 :       16705 :   tree label;
     550                 :       16705 :   if (CONTINUE_NAME (*stmt_p))
     551                 :             :     {
     552                 :          38 :       tree_pair *slot = bc_hash_map->get (CONTINUE_NAME (*stmt_p));
     553                 :          38 :       gcc_checking_assert (slot);
     554                 :          38 :       label = slot->second;
     555                 :          38 :       TREE_USED (label) = 1;
     556                 :             :     }
     557                 :             :   else
     558                 :       16667 :     label = get_bc_label (bc_continue);
     559                 :       16705 :   location_t location = EXPR_LOCATION (*stmt_p);
     560                 :       16705 :   tree jump = build1_loc (location, GOTO_EXPR, void_type_node, label);
     561                 :       16705 :   append_to_statement_list_force (pred, &stmt_list);
     562                 :       16705 :   append_to_statement_list (jump, &stmt_list);
     563                 :       16705 :   *stmt_p = stmt_list;
     564                 :       16705 : }
     565                 :             : 
     566                 :             : /* Genericize a BREAK_STMT node *STMT_P.  */
     567                 :             : 
     568                 :             : static void
     569                 :     1269048 : genericize_break_stmt (tree *stmt_p)
     570                 :             : {
     571                 :     1269048 :   tree label;
     572                 :     1269048 :   if (BREAK_NAME (*stmt_p))
     573                 :             :     {
     574                 :          48 :       tree_pair *slot = bc_hash_map->get (BREAK_NAME (*stmt_p));
     575                 :          48 :       gcc_checking_assert (slot);
     576                 :          48 :       label = slot->first;
     577                 :          48 :       TREE_USED (label) = 1;
     578                 :             :     }
     579                 :             :   else
     580                 :     1269000 :     label = get_bc_label (bc_break);
     581                 :     1269048 :   location_t location = EXPR_LOCATION (*stmt_p);
     582                 :     1269048 :   *stmt_p = build1_loc (location, GOTO_EXPR, void_type_node, label);
     583                 :     1269048 : }
     584                 :             : 
     585                 :             : /* Genericize a OMP_FOR node *STMT_P.  */
     586                 :             : 
     587                 :             : static void
     588                 :       42305 : genericize_omp_for_stmt (tree *stmt_p, int *walk_subtrees, void *data,
     589                 :             :                          walk_tree_fn func, walk_tree_lh lh)
     590                 :             : {
     591                 :       42305 :   tree stmt = *stmt_p;
     592                 :       42305 :   location_t locus = EXPR_LOCATION (stmt);
     593                 :       42305 :   tree clab = begin_bc_block (bc_continue, locus);
     594                 :             : 
     595                 :       42305 :   walk_tree_1 (&OMP_FOR_BODY (stmt), func, data, NULL, lh);
     596                 :       42305 :   if (TREE_CODE (stmt) != OMP_TASKLOOP)
     597                 :       40899 :     walk_tree_1 (&OMP_FOR_CLAUSES (stmt), func, data, NULL, lh);
     598                 :       42305 :   walk_tree_1 (&OMP_FOR_INIT (stmt), func, data, NULL, lh);
     599                 :       42305 :   walk_tree_1 (&OMP_FOR_COND (stmt), func, data, NULL, lh);
     600                 :       42305 :   walk_tree_1 (&OMP_FOR_INCR (stmt), func, data, NULL, lh);
     601                 :       42305 :   walk_tree_1 (&OMP_FOR_PRE_BODY (stmt), func, data, NULL, lh);
     602                 :       42305 :   *walk_subtrees = 0;
     603                 :             : 
     604                 :       42305 :   finish_bc_block (&OMP_FOR_BODY (stmt), bc_continue, clab);
     605                 :       42305 : }
     606                 :             : 
     607                 :             : /* Genericize a OMP_METADIRECTIVE node *STMT_P.  */
     608                 :             : 
     609                 :             : static void
     610                 :          24 : genericize_omp_metadirective_stmt (tree *stmt_p, int *walk_subtrees,
     611                 :             :                                    void *data, walk_tree_fn func,
     612                 :             :                                    walk_tree_lh lh)
     613                 :             : {
     614                 :          24 :   tree stmt = *stmt_p;
     615                 :             : 
     616                 :          24 :   for (tree variant = OMP_METADIRECTIVE_VARIANTS (stmt);
     617                 :          94 :        variant != NULL_TREE;
     618                 :          70 :        variant = TREE_CHAIN (variant))
     619                 :             :     {
     620                 :          70 :       walk_tree_1 (&OMP_METADIRECTIVE_VARIANT_DIRECTIVE (variant),
     621                 :             :                    func, data, NULL, lh);
     622                 :          70 :       walk_tree_1 (&OMP_METADIRECTIVE_VARIANT_BODY (variant),
     623                 :             :                    func, data, NULL, lh);
     624                 :             :     }
     625                 :             : 
     626                 :          24 :   *walk_subtrees = 0;
     627                 :          24 : }
     628                 :             : 
     629                 :             : /* Lower structured control flow tree nodes, such as loops.  The
     630                 :             :    STMT_P, WALK_SUBTREES, and DATA arguments are as for the walk_tree_fn
     631                 :             :    type.  FUNC and LH are language-specific functions passed to walk_tree_1
     632                 :             :    for node visiting and traversal, respectively; they are used to do
     633                 :             :    subtree processing in a language-dependent way.  */
     634                 :             : 
     635                 :             : tree
     636                 :   729395925 : c_genericize_control_stmt (tree *stmt_p, int *walk_subtrees, void *data,
     637                 :             :                            walk_tree_fn func, walk_tree_lh lh)
     638                 :             : {
     639                 :   729395925 :   tree stmt = *stmt_p;
     640                 :             : 
     641                 :   729395925 :   switch (TREE_CODE (stmt))
     642                 :             :     {
     643                 :     1561772 :     case FOR_STMT:
     644                 :     1561772 :       genericize_for_stmt (stmt_p, walk_subtrees, data, func, lh);
     645                 :     1561772 :       break;
     646                 :             : 
     647                 :      495937 :     case WHILE_STMT:
     648                 :      495937 :       genericize_while_stmt (stmt_p, walk_subtrees, data, func, lh);
     649                 :      495937 :       break;
     650                 :             : 
     651                 :     1230122 :     case DO_STMT:
     652                 :     1230122 :       genericize_do_stmt (stmt_p, walk_subtrees, data, func, lh);
     653                 :     1230122 :       break;
     654                 :             : 
     655                 :      308824 :     case SWITCH_STMT:
     656                 :      308824 :       genericize_switch_stmt (stmt_p, walk_subtrees, data, func, lh);
     657                 :      308824 :       break;
     658                 :             : 
     659                 :       16705 :     case CONTINUE_STMT:
     660                 :       16705 :       genericize_continue_stmt (stmt_p);
     661                 :       16705 :       break;
     662                 :             : 
     663                 :     1269048 :     case BREAK_STMT:
     664                 :     1269048 :       genericize_break_stmt (stmt_p);
     665                 :     1269048 :       break;
     666                 :             : 
     667                 :       42305 :     case OMP_FOR:
     668                 :       42305 :     case OMP_SIMD:
     669                 :       42305 :     case OMP_DISTRIBUTE:
     670                 :       42305 :     case OMP_LOOP:
     671                 :       42305 :     case OMP_TASKLOOP:
     672                 :       42305 :     case OMP_TILE:
     673                 :       42305 :     case OMP_UNROLL:
     674                 :       42305 :     case OACC_LOOP:
     675                 :       42305 :       genericize_omp_for_stmt (stmt_p, walk_subtrees, data, func, lh);
     676                 :       42305 :       break;
     677                 :             : 
     678                 :          24 :     case OMP_METADIRECTIVE:
     679                 :          24 :       genericize_omp_metadirective_stmt (stmt_p, walk_subtrees, data, func,
     680                 :             :                                          lh);
     681                 :          24 :       break;
     682                 :             : 
     683                 :    50440438 :     case STATEMENT_LIST:
     684                 :    50440438 :       if (TREE_SIDE_EFFECTS (stmt))
     685                 :             :         {
     686                 :    48167481 :           tree_stmt_iterator i;
     687                 :    48167481 :           int nondebug_stmts = 0;
     688                 :    48167481 :           bool clear_side_effects = true;
     689                 :             :           /* Genericization can clear TREE_SIDE_EFFECTS, e.g. when
     690                 :             :              transforming an IF_STMT into COND_EXPR.  If such stmt
     691                 :             :              appears in a STATEMENT_LIST that contains only that
     692                 :             :              stmt and some DEBUG_BEGIN_STMTs, without -g where the
     693                 :             :              STATEMENT_LIST wouldn't be present at all the resulting
     694                 :             :              expression wouldn't have TREE_SIDE_EFFECTS set, so make sure
     695                 :             :              to clear it even on the STATEMENT_LIST in such cases.  */
     696                 :    96334962 :           hash_set<tree> *pset = (c_dialect_cxx ()
     697                 :    48167481 :                                   ? nullptr
     698                 :             :                                   : static_cast<hash_set<tree> *>(data));
     699                 :   207804931 :           for (i = tsi_start (stmt); !tsi_end_p (i); tsi_next (&i))
     700                 :             :             {
     701                 :   159637450 :               tree t = tsi_stmt (i);
     702                 :   159637450 :               if (TREE_CODE (t) != DEBUG_BEGIN_STMT && nondebug_stmts < 2)
     703                 :    74708888 :                 nondebug_stmts++;
     704                 :   159637450 :               walk_tree_1 (tsi_stmt_ptr (i), func, data, pset, lh);
     705                 :   159637450 :               if (TREE_CODE (t) != DEBUG_BEGIN_STMT
     706                 :   159637450 :                   && (nondebug_stmts > 1 || TREE_SIDE_EFFECTS (tsi_stmt (i))))
     707                 :             :                 clear_side_effects = false;
     708                 :             :             }
     709                 :    48167481 :           if (clear_side_effects)
     710                 :        2567 :             TREE_SIDE_EFFECTS (stmt) = 0;
     711                 :    48167481 :           *walk_subtrees = 0;
     712                 :             :         }
     713                 :             :       break;
     714                 :             : 
     715                 :             :     default:
     716                 :             :       break;
     717                 :             :     }
     718                 :             : 
     719                 :   729395925 :   return NULL;
     720                 :             : }
     721                 :             : 
     722                 :             : 
     723                 :             : /* Wrapper for c_genericize_control_stmt to allow it to be used as a walk_tree
     724                 :             :    callback.  This is appropriate for C; C++ calls c_genericize_control_stmt
     725                 :             :    directly.  */
     726                 :             : 
     727                 :             : static tree
     728                 :   678385033 : c_genericize_control_r (tree *stmt_p, int *walk_subtrees, void *data)
     729                 :             : {
     730                 :   678385033 :   c_genericize_control_stmt (stmt_p, walk_subtrees, data,
     731                 :             :                              c_genericize_control_r, NULL);
     732                 :   678385033 :   return NULL;
     733                 :             : }
     734                 :             : 
     735                 :             : /* Convert the tree representation of FNDECL from C frontend trees to
     736                 :             :    GENERIC.  */
     737                 :             : 
     738                 :             : void
     739                 :    76236126 : c_genericize (tree fndecl)
     740                 :             : {
     741                 :    76236126 :   dump_file_info *dfi;
     742                 :    76236126 :   FILE *dump_orig;
     743                 :    76236126 :   dump_flags_t local_dump_flags;
     744                 :    76236126 :   struct cgraph_node *cgn;
     745                 :             : 
     746                 :    76236126 :   if (flag_sanitize & SANITIZE_BOUNDS)
     747                 :             :     {
     748                 :       67812 :       hash_set<tree> pset;
     749                 :       67812 :       walk_tree (&DECL_SAVED_TREE (fndecl), ubsan_walk_array_refs_r, &pset,
     750                 :             :                  &pset);
     751                 :       67812 :     }
     752                 :             : 
     753                 :             :   /* Genericize loops and other structured control constructs.  The C++
     754                 :             :      front end has already done this in lang-specific code.  */
     755                 :    76236126 :   if (!c_dialect_cxx ())
     756                 :             :     {
     757                 :    36851329 :       bc_state_t save_state;
     758                 :    36851329 :       push_cfun (DECL_STRUCT_FUNCTION (fndecl));
     759                 :    36851329 :       save_bc_state (&save_state);
     760                 :    36851329 :       hash_set<tree> pset;
     761                 :    36851329 :       walk_tree (&DECL_SAVED_TREE (fndecl), c_genericize_control_r, &pset,
     762                 :             :                  &pset);
     763                 :    36851343 :       delete bc_hash_map;
     764                 :    36851329 :       bc_hash_map = NULL;
     765                 :    36851329 :       restore_bc_state (&save_state);
     766                 :    36851329 :       pop_cfun ();
     767                 :    36851329 :     }
     768                 :             : 
     769                 :    76236126 :   if (warn_duplicated_branches)
     770                 :         130 :     walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
     771                 :             :                                   do_warn_duplicated_branches_r, NULL);
     772                 :             : 
     773                 :             :   /* Dump the C-specific tree IR.  */
     774                 :    76236126 :   dfi = g->get_dumps ()->get_dump_file_info (TDI_original);
     775                 :    76236126 :   dump_orig = dfi->pstream;
     776                 :    76236126 :   local_dump_flags = dfi->pflags;
     777                 :    76236126 :   if (dump_orig)
     778                 :             :     {
     779                 :        5510 :       fprintf (dump_orig, "\n;; Function %s",
     780                 :        5510 :                lang_hooks.decl_printable_name (fndecl, 2));
     781                 :        5510 :       fprintf (dump_orig, " (%s)\n",
     782                 :        5510 :                (!DECL_ASSEMBLER_NAME_SET_P (fndecl) ? "null"
     783                 :          60 :                 : IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl))));
     784                 :        5510 :       fprintf (dump_orig, ";; enabled by -%s\n", dump_flag_name (TDI_original));
     785                 :        5510 :       fprintf (dump_orig, "\n");
     786                 :             : 
     787                 :        5510 :       if (local_dump_flags & TDF_RAW)
     788                 :           1 :         dump_node (DECL_SAVED_TREE (fndecl),
     789                 :             :                    TDF_SLIM | local_dump_flags, dump_orig);
     790                 :             :       else
     791                 :        5509 :         print_c_tree (dump_orig, DECL_SAVED_TREE (fndecl), local_dump_flags);
     792                 :        5510 :       fprintf (dump_orig, "\n");
     793                 :             :     }
     794                 :             : 
     795                 :             :   /* Dump all nested functions now.  */
     796                 :    76236126 :   cgn = cgraph_node::get_create (fndecl);
     797                 :    76237652 :   for (cgn = first_nested_function (cgn);
     798                 :    76237652 :        cgn; cgn = next_nested_function (cgn))
     799                 :        1526 :     c_genericize (cgn->decl);
     800                 :    76236126 : }
     801                 :             : 
     802                 :             : static void
     803                 :           0 : add_block_to_enclosing (tree block)
     804                 :             : {
     805                 :           0 :   unsigned i;
     806                 :           0 :   tree enclosing;
     807                 :           0 :   gbind *bind;
     808                 :           0 :   vec<gbind *> stack = gimple_bind_expr_stack ();
     809                 :             : 
     810                 :           0 :   FOR_EACH_VEC_ELT (stack, i, bind)
     811                 :           0 :     if (gimple_bind_block (bind))
     812                 :             :       break;
     813                 :             : 
     814                 :           0 :   enclosing = gimple_bind_block (bind);
     815                 :           0 :   BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
     816                 :           0 : }
     817                 :             : 
     818                 :             : /* Genericize a scope by creating a new BIND_EXPR.
     819                 :             :    BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
     820                 :             :      In the latter case, we need to create a new BLOCK and add it to the
     821                 :             :      BLOCK_SUBBLOCKS of the enclosing block.
     822                 :             :    BODY is a chain of C _STMT nodes for the contents of the scope, to be
     823                 :             :      genericized.  */
     824                 :             : 
     825                 :             : tree
     826                 :   129115289 : c_build_bind_expr (location_t loc, tree block, tree body)
     827                 :             : {
     828                 :   129115289 :   tree decls, bind;
     829                 :             : 
     830                 :   129115289 :   if (block == NULL_TREE)
     831                 :             :     decls = NULL_TREE;
     832                 :    58051987 :   else if (TREE_CODE (block) == BLOCK)
     833                 :    58051987 :     decls = BLOCK_VARS (block);
     834                 :             :   else
     835                 :             :     {
     836                 :           0 :       decls = block;
     837                 :           0 :       if (DECL_ARTIFICIAL (decls))
     838                 :             :         block = NULL_TREE;
     839                 :             :       else
     840                 :             :         {
     841                 :           0 :           block = make_node (BLOCK);
     842                 :           0 :           BLOCK_VARS (block) = decls;
     843                 :           0 :           add_block_to_enclosing (block);
     844                 :             :         }
     845                 :             :     }
     846                 :             : 
     847                 :   129115289 :   if (!body)
     848                 :           0 :     body = build_empty_stmt (loc);
     849                 :   129115289 :   if (decls || block)
     850                 :             :     {
     851                 :    58051987 :       bind = build3 (BIND_EXPR, void_type_node, decls, body, block);
     852                 :    58051987 :       TREE_SIDE_EFFECTS (bind) = 1;
     853                 :    58051987 :       SET_EXPR_LOCATION (bind, loc);
     854                 :             :     }
     855                 :             :   else
     856                 :             :     bind = body;
     857                 :             : 
     858                 :   129115289 :   return bind;
     859                 :             : }
     860                 :             : 
     861                 :             : /* Helper for c_gimplify_expr: test if target supports fma-like FN.  */
     862                 :             : 
     863                 :             : static bool
     864                 :           0 : fma_supported_p (enum internal_fn fn, tree type)
     865                 :             : {
     866                 :           0 :   return direct_internal_fn_supported_p (fn, type, OPTIMIZE_FOR_BOTH);
     867                 :             : }
     868                 :             : 
     869                 :             : /* Gimplification of expression trees.  */
     870                 :             : 
     871                 :             : /* Do C-specific gimplification on *EXPR_P.  PRE_P and POST_P are as in
     872                 :             :    gimplify_expr.  */
     873                 :             : 
     874                 :             : int
     875                 :   252537148 : c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
     876                 :             :                  gimple_seq *post_p ATTRIBUTE_UNUSED)
     877                 :             : {
     878                 :   252537148 :   enum tree_code code = TREE_CODE (*expr_p);
     879                 :             : 
     880                 :   252537148 :   switch (code)
     881                 :             :     {
     882                 :      364363 :     case LSHIFT_EXPR:
     883                 :      364363 :     case RSHIFT_EXPR:
     884                 :      364363 :     case LROTATE_EXPR:
     885                 :      364363 :     case RROTATE_EXPR:
     886                 :      364363 :       {
     887                 :             :         /* We used to convert the right operand of a shift-expression
     888                 :             :            to an integer_type_node in the FEs.  But it is unnecessary
     889                 :             :            and not desirable for diagnostics and sanitizers.  We keep
     890                 :             :            this here to not pessimize the code, but we convert to an
     891                 :             :            unsigned type, because negative shift counts are undefined
     892                 :             :            anyway.
     893                 :             :            We should get rid of this conversion when we have a proper
     894                 :             :            type demotion/promotion pass.  */
     895                 :      364363 :         tree *op1_p = &TREE_OPERAND (*expr_p, 1);
     896                 :      364363 :         if (!error_operand_p (*op1_p)
     897                 :      364362 :             && !VECTOR_TYPE_P (TREE_TYPE (*op1_p))
     898                 :      362647 :             && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)),
     899                 :             :                                     unsigned_type_node)
     900                 :      667771 :             && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)),
     901                 :             :                                     integer_type_node))
     902                 :             :           /* Make sure to unshare the result, tree sharing is invalid
     903                 :             :              during gimplification.  */
     904                 :       25198 :           *op1_p = unshare_expr (convert (unsigned_type_node, *op1_p));
     905                 :             :         break;
     906                 :             :       }
     907                 :             : 
     908                 :     1117941 :     case PREINCREMENT_EXPR:
     909                 :     1117941 :     case PREDECREMENT_EXPR:
     910                 :     1117941 :     case POSTINCREMENT_EXPR:
     911                 :     1117941 :     case POSTDECREMENT_EXPR:
     912                 :     1117941 :       {
     913                 :     1117941 :         tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
     914                 :     1117941 :         if (INTEGRAL_TYPE_P (type) && c_promoting_integer_type_p (type))
     915                 :             :           {
     916                 :        5510 :             if (!TYPE_OVERFLOW_WRAPS (type))
     917                 :        3231 :               type = unsigned_type_for (type);
     918                 :        5510 :             return gimplify_self_mod_expr (expr_p, pre_p, post_p, 1, type);
     919                 :             :           }
     920                 :             :         break;
     921                 :             :       }
     922                 :             : 
     923                 :     7431398 :     case PLUS_EXPR:
     924                 :     7431398 :     case MINUS_EXPR:
     925                 :     7431398 :       {
     926                 :     7431398 :         tree type = TREE_TYPE (*expr_p);
     927                 :             :         /* For -ffp-contract=on we need to attempt FMA contraction only
     928                 :             :            during initial gimplification.  Late contraction across statement
     929                 :             :            boundaries would violate language semantics.  */
     930                 :     7431398 :         if (SCALAR_FLOAT_TYPE_P (type)
     931                 :      955209 :             && flag_fp_contract_mode == FP_CONTRACT_ON
     932                 :           0 :             && cfun && !(cfun->curr_properties & PROP_gimple_any)
     933                 :     7431398 :             && fma_supported_p (IFN_FMA, type))
     934                 :             :           {
     935                 :           0 :             bool neg_mul = false, neg_add = code == MINUS_EXPR;
     936                 :             : 
     937                 :           0 :             tree *op0_p = &TREE_OPERAND (*expr_p, 0);
     938                 :           0 :             tree *op1_p = &TREE_OPERAND (*expr_p, 1);
     939                 :             : 
     940                 :             :             /* Look for ±(x * y) ± z, swapping operands if necessary.  */
     941                 :           0 :             if (TREE_CODE (*op0_p) == NEGATE_EXPR
     942                 :           0 :                 && TREE_CODE (TREE_OPERAND (*op0_p, 0)) == MULT_EXPR)
     943                 :             :               /* '*EXPR_P' is '-(x * y) ± z'.  This is fine.  */;
     944                 :           0 :             else if (TREE_CODE (*op0_p) != MULT_EXPR)
     945                 :             :               {
     946                 :             :                 std::swap (op0_p, op1_p);
     947                 :             :                 std::swap (neg_mul, neg_add);
     948                 :             :               }
     949                 :           0 :             if (TREE_CODE (*op0_p) == NEGATE_EXPR)
     950                 :             :               {
     951                 :           0 :                 op0_p = &TREE_OPERAND (*op0_p, 0);
     952                 :           0 :                 neg_mul = !neg_mul;
     953                 :             :               }
     954                 :           0 :             if (TREE_CODE (*op0_p) != MULT_EXPR)
     955                 :             :               break;
     956                 :           0 :             auto_vec<tree, 3> ops (3);
     957                 :           0 :             ops.quick_push (TREE_OPERAND (*op0_p, 0));
     958                 :           0 :             ops.quick_push (TREE_OPERAND (*op0_p, 1));
     959                 :           0 :             ops.quick_push (*op1_p);
     960                 :             : 
     961                 :           0 :             enum internal_fn ifn = IFN_FMA;
     962                 :           0 :             if (neg_mul)
     963                 :             :               {
     964                 :           0 :                 if (fma_supported_p (IFN_FNMA, type))
     965                 :             :                   ifn = IFN_FNMA;
     966                 :             :                 else
     967                 :           0 :                   ops[0] = build1 (NEGATE_EXPR, type, ops[0]);
     968                 :             :               }
     969                 :           0 :             if (neg_add)
     970                 :             :               {
     971                 :           0 :                 enum internal_fn ifn2 = ifn == IFN_FMA ? IFN_FMS : IFN_FNMS;
     972                 :           0 :                 if (fma_supported_p (ifn2, type))
     973                 :             :                   ifn = ifn2;
     974                 :             :                 else
     975                 :           0 :                   ops[2] = build1 (NEGATE_EXPR, type, ops[2]);
     976                 :             :               }
     977                 :             :             /* Avoid gimplify_arg: it emits all side effects into *PRE_P.  */
     978                 :           0 :             for (auto &&op : ops)
     979                 :           0 :               if (gimplify_expr (&op, pre_p, post_p, is_gimple_val, fb_rvalue)
     980                 :             :                   == GS_ERROR)
     981                 :             :                 return GS_ERROR;
     982                 :             : 
     983                 :           0 :             gcall *call = gimple_build_call_internal_vec (ifn, ops);
     984                 :           0 :             gimple_seq_add_stmt_without_update (pre_p, call);
     985                 :           0 :             *expr_p = create_tmp_var (type);
     986                 :           0 :             gimple_call_set_lhs (call, *expr_p);
     987                 :           0 :             return GS_ALL_DONE;
     988                 :           0 :           }
     989                 :             :         break;
     990                 :             :       }
     991                 :             : 
     992                 :     3728582 :     case CALL_EXPR:
     993                 :     3728582 :       {
     994                 :     3728582 :         tree fndecl = get_callee_fndecl (*expr_p);
     995                 :     3728582 :         if (fndecl
     996                 :     3479415 :             && fndecl_built_in_p (fndecl, BUILT_IN_CLZG, BUILT_IN_CTZG)
     997                 :          52 :             && call_expr_nargs (*expr_p) == 2
     998                 :     3728634 :             && TREE_CODE (CALL_EXPR_ARG (*expr_p, 1)) != INTEGER_CST)
     999                 :             :           {
    1000                 :          52 :             tree a = save_expr (CALL_EXPR_ARG (*expr_p, 0));
    1001                 :          52 :             tree c = build_call_expr_loc (EXPR_LOCATION (*expr_p),
    1002                 :             :                                           fndecl, 1, a);
    1003                 :         104 :             *expr_p = build3_loc (EXPR_LOCATION (*expr_p), COND_EXPR,
    1004                 :             :                                   integer_type_node,
    1005                 :          52 :                                   build2_loc (EXPR_LOCATION (*expr_p),
    1006                 :             :                                               NE_EXPR, boolean_type_node, a,
    1007                 :          52 :                                               build_zero_cst (TREE_TYPE (a))),
    1008                 :          52 :                                   c, CALL_EXPR_ARG (*expr_p, 1));
    1009                 :          52 :             return GS_OK;
    1010                 :             :           }
    1011                 :             :         break;
    1012                 :             :       }
    1013                 :             : 
    1014                 :             :     default:;
    1015                 :             :     }
    1016                 :             : 
    1017                 :             :   return GS_UNHANDLED;
    1018                 :             : }
        

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.