LCOV - code coverage report
Current view: top level - gcc/c-family - c-gimplify.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 86.8 % 401 348
Test Date: 2024-04-13 14:00:49 Functions: 90.9 % 22 20
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-2024 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                 :             : 
      47                 :             : /*  The gimplification pass converts the language-dependent trees
      48                 :             :     (ld-trees) emitted by the parser into language-independent trees
      49                 :             :     (li-trees) that are the target of SSA analysis and transformations.
      50                 :             : 
      51                 :             :     Language-independent trees are based on the SIMPLE intermediate
      52                 :             :     representation used in the McCAT compiler framework:
      53                 :             : 
      54                 :             :     "Designing the McCAT Compiler Based on a Family of Structured
      55                 :             :     Intermediate Representations,"
      56                 :             :     L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
      57                 :             :     Proceedings of the 5th International Workshop on Languages and
      58                 :             :     Compilers for Parallel Computing, no. 757 in Lecture Notes in
      59                 :             :     Computer Science, New Haven, Connecticut, pp. 406-420,
      60                 :             :     Springer-Verlag, August 3-5, 1992.
      61                 :             : 
      62                 :             :     http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
      63                 :             : 
      64                 :             :     Basically, we walk down gimplifying the nodes that we encounter.  As we
      65                 :             :     walk back up, we check that they fit our constraints, and copy them
      66                 :             :     into temporaries if not.  */
      67                 :             : 
      68                 :             : /* Callback for c_genericize.  */
      69                 :             : 
      70                 :             : static tree
      71                 :      997648 : ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
      72                 :             : {
      73                 :      997648 :   hash_set<tree> *pset = (hash_set<tree> *) data;
      74                 :             : 
      75                 :      997648 :   if (TREE_CODE (*tp) == BIND_EXPR)
      76                 :             :     {
      77                 :             :       /* Since walk_tree doesn't call the callback function on the decls
      78                 :             :          in BIND_EXPR_VARS, we have to walk them manually, so we can avoid
      79                 :             :          instrumenting DECL_INITIAL of TREE_STATIC vars.  */
      80                 :       50183 :       *walk_subtrees = 0;
      81                 :       63648 :       for (tree decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl))
      82                 :             :         {
      83                 :       13465 :           if (TREE_STATIC (decl))
      84                 :          98 :             continue;
      85                 :       13367 :           walk_tree (&DECL_INITIAL (decl), ubsan_walk_array_refs_r, pset,
      86                 :             :                      pset);
      87                 :       13367 :           walk_tree (&DECL_SIZE (decl), ubsan_walk_array_refs_r, pset, pset);
      88                 :       13367 :           walk_tree (&DECL_SIZE_UNIT (decl), ubsan_walk_array_refs_r, pset,
      89                 :             :                      pset);
      90                 :             :         }
      91                 :       50183 :       walk_tree (&BIND_EXPR_BODY (*tp), ubsan_walk_array_refs_r, pset, pset);
      92                 :             :     }
      93                 :      947465 :   else if (TREE_CODE (*tp) == ADDR_EXPR
      94                 :      947465 :            && TREE_CODE (TREE_OPERAND (*tp, 0)) == ARRAY_REF)
      95                 :             :     {
      96                 :         276 :       ubsan_maybe_instrument_array_ref (&TREE_OPERAND (*tp, 0), true);
      97                 :             :       /* Make sure ubsan_maybe_instrument_array_ref is not called again
      98                 :             :          on the ARRAY_REF, the above call might not instrument anything
      99                 :             :          as the index might be constant or masked, so ensure it is not
     100                 :             :          walked again and walk its subtrees manually.  */
     101                 :         276 :       tree aref = TREE_OPERAND (*tp, 0);
     102                 :         276 :       pset->add (aref);
     103                 :         276 :       *walk_subtrees = 0;
     104                 :         276 :       walk_tree (&TREE_OPERAND (aref, 0), ubsan_walk_array_refs_r, pset, pset);
     105                 :         276 :       walk_tree (&TREE_OPERAND (aref, 1), ubsan_walk_array_refs_r, pset, pset);
     106                 :         276 :       walk_tree (&TREE_OPERAND (aref, 2), ubsan_walk_array_refs_r, pset, pset);
     107                 :         276 :       walk_tree (&TREE_OPERAND (aref, 3), ubsan_walk_array_refs_r, pset, pset);
     108                 :             :     }
     109                 :      947189 :   else if (TREE_CODE (*tp) == ARRAY_REF)
     110                 :        3747 :     ubsan_maybe_instrument_array_ref (tp, false);
     111                 :      943442 :   else if (TREE_CODE (*tp) == MODIFY_EXPR)
     112                 :             :     {
     113                 :             :       /* Since r7-1900, we gimplify RHS before LHS.  Consider
     114                 :             :            a[b] |= c;
     115                 :             :          wherein we can have a single shared tree a[b] in both LHS and RHS.
     116                 :             :          If we only instrument the LHS and the access is invalid, the program
     117                 :             :          could crash before emitting a UBSan error.  So instrument the RHS
     118                 :             :          first.  */
     119                 :       51562 :       *walk_subtrees = 0;
     120                 :       51562 :       walk_tree (&TREE_OPERAND (*tp, 1), ubsan_walk_array_refs_r, pset, pset);
     121                 :       51562 :       walk_tree (&TREE_OPERAND (*tp, 0), ubsan_walk_array_refs_r, pset, pset);
     122                 :             :     }
     123                 :      997648 :   return NULL_TREE;
     124                 :             : }
     125                 :             : 
     126                 :             : /* Gimplification of statement trees.  */
     127                 :             : 
     128                 :             : /* Local declarations.  */
     129                 :             : 
     130                 :             : enum bc_t { bc_break = 0, bc_continue = 1 };
     131                 :             : 
     132                 :             : /* Stack of labels which are targets for "break" or "continue",
     133                 :             :    linked through TREE_CHAIN.  */
     134                 :             : static tree bc_label[2];
     135                 :             : 
     136                 :             : /* Begin a scope which can be exited by a break or continue statement.  BC
     137                 :             :    indicates which.
     138                 :             : 
     139                 :             :    Just creates a label with location LOCATION and pushes it into the current
     140                 :             :    context.  */
     141                 :             : 
     142                 :             : static tree
     143                 :     6652045 : begin_bc_block (enum bc_t bc, location_t location)
     144                 :             : {
     145                 :     6652045 :   tree label = create_artificial_label (location);
     146                 :     6652045 :   DECL_CHAIN (label) = bc_label[bc];
     147                 :     6652045 :   bc_label[bc] = label;
     148                 :     6652045 :   if (bc == bc_break)
     149                 :     3452474 :     LABEL_DECL_BREAK (label) = true;
     150                 :             :   else
     151                 :     3199571 :     LABEL_DECL_CONTINUE (label) = true;
     152                 :     6652045 :   return label;
     153                 :             : }
     154                 :             : 
     155                 :             : /* Finish a scope which can be exited by a break or continue statement.
     156                 :             :    LABEL was returned from the most recent call to begin_bc_block.  BLOCK is
     157                 :             :    an expression for the contents of the scope.
     158                 :             : 
     159                 :             :    If we saw a break (or continue) in the scope, append a LABEL_EXPR to
     160                 :             :    BLOCK.  Otherwise, just forget the label.  */
     161                 :             : 
     162                 :             : static void
     163                 :     6652045 : finish_bc_block (tree *block, enum bc_t bc, tree label)
     164                 :             : {
     165                 :     6652045 :   gcc_assert (label == bc_label[bc]);
     166                 :             : 
     167                 :     6652045 :   if (TREE_USED (label))
     168                 :     2673794 :     append_to_statement_list (build1 (LABEL_EXPR, void_type_node, label),
     169                 :             :                               block);
     170                 :             : 
     171                 :     6652045 :   bc_label[bc] = DECL_CHAIN (label);
     172                 :     6652045 :   DECL_CHAIN (label) = NULL_TREE;
     173                 :     6652045 : }
     174                 :             : 
     175                 :             : /* Allow saving and restoring break/continue state.  */
     176                 :             : 
     177                 :             : void
     178                 :    69610300 : save_bc_state (bc_state_t *state)
     179                 :             : {
     180                 :    69610300 :   state->bc_label[bc_break] = bc_label[bc_break];
     181                 :    69610300 :   state->bc_label[bc_continue] = bc_label[bc_continue];
     182                 :    69610300 :   bc_label[bc_break] = NULL_TREE;
     183                 :    69610300 :   bc_label[bc_continue] = NULL_TREE;
     184                 :    69610300 : }
     185                 :             : 
     186                 :             : void
     187                 :    69610300 : restore_bc_state (bc_state_t *state)
     188                 :             : {
     189                 :    69610300 :   gcc_assert (bc_label[bc_break] == NULL);
     190                 :    69610300 :   gcc_assert (bc_label[bc_continue] == NULL);
     191                 :    69610300 :   bc_label[bc_break] = state->bc_label[bc_break];
     192                 :    69610300 :   bc_label[bc_continue] = state->bc_label[bc_continue];
     193                 :    69610300 : }
     194                 :             : 
     195                 :             : /* Get the LABEL_EXPR to represent a break or continue statement
     196                 :             :    in the current block scope.  BC indicates which.  */
     197                 :             : 
     198                 :             : static tree
     199                 :     3693776 : get_bc_label (enum bc_t bc)
     200                 :             : {
     201                 :     3693776 :   tree label = bc_label[bc];
     202                 :     3693776 :   gcc_assert (label);
     203                 :             : 
     204                 :             :   /* Mark the label used for finish_bc_block.  */
     205                 :     3693776 :   TREE_USED (label) = 1;
     206                 :     3693776 :   return label;
     207                 :             : }
     208                 :             : 
     209                 :             : /* Return the location from EXPR, or OR_LOC if the former is unknown.  */
     210                 :             : 
     211                 :             : location_t
     212                 :     7597768 : expr_loc_or_loc (const_tree expr, location_t or_loc)
     213                 :             : {
     214                 :     7597768 :   tree t = CONST_CAST_TREE (expr);
     215                 :     7597768 :   location_t loc = UNKNOWN_LOCATION;
     216                 :     7597768 :   if (t)
     217                 :     5822333 :     loc = EXPR_LOCATION (t);
     218                 :     4751015 :   if (loc == UNKNOWN_LOCATION)
     219                 :     4039923 :     loc = or_loc;
     220                 :     7597768 :   return loc;
     221                 :             : }
     222                 :             : 
     223                 :             : /* Build a generic representation of one of the C loop forms.  COND is the
     224                 :             :    loop condition or NULL_TREE.  BODY is the (possibly compound) statement
     225                 :             :    controlled by the loop.  INCR is the increment expression of a for-loop,
     226                 :             :    or NULL_TREE.  COND_IS_FIRST indicates whether the condition is
     227                 :             :    evaluated before the loop body as in while and for loops, or after the
     228                 :             :    loop body as in do-while loops.  */
     229                 :             : 
     230                 :             : static void
     231                 :     3157809 : genericize_c_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
     232                 :             :                    tree incr, bool cond_is_first, int *walk_subtrees,
     233                 :             :                    void *data, walk_tree_fn func, walk_tree_lh lh)
     234                 :             : {
     235                 :     3157809 :   tree blab, clab;
     236                 :     3157809 :   tree entry = NULL, exit = NULL, t;
     237                 :     3157809 :   tree stmt_list = NULL;
     238                 :     3157809 :   location_t cond_locus = expr_loc_or_loc (cond, start_locus);
     239                 :     3157809 :   location_t incr_locus = expr_loc_or_loc (incr, start_locus);
     240                 :             : 
     241                 :     3157809 :   protected_set_expr_location_if_unset (incr, start_locus);
     242                 :             : 
     243                 :     3157809 :   walk_tree_1 (&cond, func, data, NULL, lh);
     244                 :     3157809 :   walk_tree_1 (&incr, func, data, NULL, lh);
     245                 :             : 
     246                 :     3157809 :   blab = begin_bc_block (bc_break, start_locus);
     247                 :     3157809 :   clab = begin_bc_block (bc_continue, start_locus);
     248                 :             : 
     249                 :     3157809 :   walk_tree_1 (&body, func, data, NULL, lh);
     250                 :     3157809 :   *walk_subtrees = 0;
     251                 :             : 
     252                 :             :   /* If condition is zero don't generate a loop construct.  */
     253                 :     3157809 :   if (cond && integer_zerop (cond))
     254                 :             :     {
     255                 :     1015480 :       if (cond_is_first)
     256                 :             :         {
     257                 :         166 :           t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
     258                 :             :                           get_bc_label (bc_break));
     259                 :         166 :           append_to_statement_list (t, &stmt_list);
     260                 :             :         }
     261                 :             :     }
     262                 :             :   else
     263                 :             :     {
     264                 :             :       /* Expand to gotos.  */
     265                 :     2142329 :       tree top = build1 (LABEL_EXPR, void_type_node,
     266                 :             :                          create_artificial_label (start_locus));
     267                 :             : 
     268                 :             :       /* If we have an exit condition, then we build an IF with gotos either
     269                 :             :          out of the loop, or to the top of it.  If there's no exit condition,
     270                 :             :          then we just build a jump back to the top.  */
     271                 :     2142329 :       exit = build1 (GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL (top));
     272                 :             : 
     273                 :     2142329 :       if (cond && !integer_nonzerop (cond))
     274                 :             :         {
     275                 :             :           /* Canonicalize the loop condition to the end.  This means
     276                 :             :              generating a branch to the loop condition.  Reuse the
     277                 :             :              continue label, if there is no incr expression.  */
     278                 :     2023265 :           if (cond_is_first)
     279                 :             :             {
     280                 :     1878193 :               if (incr)
     281                 :             :                 {
     282                 :     1444379 :                   entry = build1 (LABEL_EXPR, void_type_node,
     283                 :             :                                   create_artificial_label (start_locus));
     284                 :     2888758 :                   t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
     285                 :     1444379 :                                   LABEL_EXPR_LABEL (entry));
     286                 :             :                 }
     287                 :             :               else
     288                 :      433814 :                 t = build1_loc (start_locus, GOTO_EXPR, void_type_node,
     289                 :             :                                 get_bc_label (bc_continue));
     290                 :     1878193 :               append_to_statement_list (t, &stmt_list);
     291                 :             :             }
     292                 :             : 
     293                 :     2023265 :           t = build1 (GOTO_EXPR, void_type_node, get_bc_label (bc_break));
     294                 :     2023265 :           exit = fold_build3_loc (cond_locus,
     295                 :             :                                   COND_EXPR, void_type_node, cond, exit, t);
     296                 :             :         }
     297                 :             :       else
     298                 :             :         {
     299                 :             :           /* For the backward-goto's location of an unconditional loop
     300                 :             :              use the beginning of the body, or, if there is none, the
     301                 :             :              top of the loop.  */
     302                 :      119064 :           location_t loc = expr_loc_or_loc (expr_first (body),
     303                 :             :                                             start_locus);
     304                 :      119064 :           SET_EXPR_LOCATION (exit, loc);
     305                 :             :         }
     306                 :     2142329 :       append_to_statement_list (top, &stmt_list);
     307                 :             :     }
     308                 :             : 
     309                 :     3157809 :   append_to_statement_list (body, &stmt_list);
     310                 :     3157809 :   if (c_dialect_cxx ()
     311                 :     2718893 :       && stmt_list
     312                 :     2716982 :       && TREE_CODE (stmt_list) == STATEMENT_LIST)
     313                 :             :     {
     314                 :     2716982 :       tree_stmt_iterator tsi = tsi_last (stmt_list);
     315                 :     2716982 :       if (!tsi_end_p (tsi))
     316                 :             :         {
     317                 :     2716982 :           tree t = *tsi;
     318                 :     2716982 :           while (TREE_CODE (t) == CLEANUP_POINT_EXPR
     319                 :             :                  || TREE_CODE (t) == EXPR_STMT
     320                 :     4899319 :                  || CONVERT_EXPR_CODE_P (TREE_CODE (t)))
     321                 :     2182337 :             t = TREE_OPERAND (t, 0);
     322                 :             :           /* For C++, if iteration statement body ends with fallthrough
     323                 :             :              statement, mark it such that we diagnose it even if next
     324                 :             :              statement would be labeled statement with case/default label.  */
     325                 :     2716982 :           if (TREE_CODE (t) == CALL_EXPR
     326                 :       95761 :               && !CALL_EXPR_FN (t)
     327                 :     2716994 :               && CALL_EXPR_IFN (t) == IFN_FALLTHROUGH)
     328                 :          12 :             TREE_NOTHROW (t) = 1;
     329                 :             :         }
     330                 :             :     }
     331                 :     3157809 :   finish_bc_block (&stmt_list, bc_continue, clab);
     332                 :     3157809 :   if (incr)
     333                 :             :     {
     334                 :     1446876 :       if (MAY_HAVE_DEBUG_MARKER_STMTS && incr_locus != UNKNOWN_LOCATION)
     335                 :             :         {
     336                 :     1163086 :           tree d = build0 (DEBUG_BEGIN_STMT, void_type_node);
     337                 :     1163086 :           SET_EXPR_LOCATION (d, expr_loc_or_loc (incr, start_locus));
     338                 :     1163086 :           append_to_statement_list (d, &stmt_list);
     339                 :             :         }
     340                 :     1446876 :       append_to_statement_list (incr, &stmt_list);
     341                 :             :     }
     342                 :     3157809 :   append_to_statement_list (entry, &stmt_list);
     343                 :             : 
     344                 :     3157809 :   if (MAY_HAVE_DEBUG_MARKER_STMTS && cond_locus != UNKNOWN_LOCATION)
     345                 :             :     {
     346                 :     2675103 :       tree d = build0 (DEBUG_BEGIN_STMT, void_type_node);
     347                 :     2675103 :       SET_EXPR_LOCATION (d, cond_locus);
     348                 :     2675103 :       append_to_statement_list (d, &stmt_list);
     349                 :             :     }
     350                 :     3157809 :   append_to_statement_list (exit, &stmt_list);
     351                 :     3157809 :   finish_bc_block (&stmt_list, bc_break, blab);
     352                 :     3157809 :   if (!stmt_list)
     353                 :        3583 :     stmt_list = build_empty_stmt (start_locus);
     354                 :             : 
     355                 :     3157809 :   *stmt_p = stmt_list;
     356                 :     3157809 : }
     357                 :             : 
     358                 :             : /* Genericize a FOR_STMT node *STMT_P.  */
     359                 :             : 
     360                 :             : static void
     361                 :     1514169 : genericize_for_stmt (tree *stmt_p, int *walk_subtrees, void *data,
     362                 :             :                      walk_tree_fn func, walk_tree_lh lh)
     363                 :             : {
     364                 :     1514169 :   tree stmt = *stmt_p;
     365                 :     1514169 :   tree expr = NULL;
     366                 :     1514169 :   tree loop;
     367                 :     1514169 :   tree init = FOR_INIT_STMT (stmt);
     368                 :             : 
     369                 :     1514169 :   if (init)
     370                 :             :     {
     371                 :           0 :       walk_tree_1 (&init, func, data, NULL, lh);
     372                 :           0 :       append_to_statement_list (init, &expr);
     373                 :             :     }
     374                 :             : 
     375                 :     3028338 :   genericize_c_loop (&loop, EXPR_LOCATION (stmt), FOR_COND (stmt),
     376                 :     1514169 :                      FOR_BODY (stmt), FOR_EXPR (stmt), 1, walk_subtrees,
     377                 :             :                      data, func, lh);
     378                 :     1514169 :   append_to_statement_list (loop, &expr);
     379                 :     1514169 :   if (expr == NULL_TREE)
     380                 :           0 :     expr = loop;
     381                 :     1514169 :   *stmt_p = expr;
     382                 :     1514169 : }
     383                 :             : 
     384                 :             : /* Genericize a WHILE_STMT node *STMT_P.  */
     385                 :             : 
     386                 :             : static void
     387                 :      482868 : genericize_while_stmt (tree *stmt_p, int *walk_subtrees, void *data,
     388                 :             :                        walk_tree_fn func, walk_tree_lh lh)
     389                 :             : {
     390                 :      482868 :   tree stmt = *stmt_p;
     391                 :      965736 :   genericize_c_loop (stmt_p, EXPR_LOCATION (stmt), WHILE_COND (stmt),
     392                 :      482868 :                      WHILE_BODY (stmt), NULL_TREE, 1, walk_subtrees,
     393                 :             :                      data, func, lh);
     394                 :      482868 : }
     395                 :             : 
     396                 :             : /* Genericize a DO_STMT node *STMT_P.  */
     397                 :             : 
     398                 :             : static void
     399                 :     1160772 : genericize_do_stmt (tree *stmt_p, int *walk_subtrees, void *data,
     400                 :             :                     walk_tree_fn func, walk_tree_lh lh)
     401                 :             : {
     402                 :     1160772 :   tree stmt = *stmt_p;
     403                 :     2321544 :   genericize_c_loop (stmt_p, EXPR_LOCATION (stmt), DO_COND (stmt),
     404                 :     1160772 :                      DO_BODY (stmt), NULL_TREE, 0, walk_subtrees,
     405                 :             :                      data, func, lh);
     406                 :     1160772 : }
     407                 :             : 
     408                 :             : /* Genericize a SWITCH_STMT node *STMT_P by turning it into a SWITCH_EXPR.  */
     409                 :             : 
     410                 :             : static void
     411                 :      294665 : genericize_switch_stmt (tree *stmt_p, int *walk_subtrees, void *data,
     412                 :             :                         walk_tree_fn func, walk_tree_lh lh)
     413                 :             : {
     414                 :      294665 :   tree stmt = *stmt_p;
     415                 :      294665 :   tree break_block, body, cond, type;
     416                 :      294665 :   location_t stmt_locus = EXPR_LOCATION (stmt);
     417                 :             : 
     418                 :      294665 :   body = SWITCH_STMT_BODY (stmt);
     419                 :      294665 :   if (!body)
     420                 :           0 :     body = build_empty_stmt (stmt_locus);
     421                 :      294665 :   cond = SWITCH_STMT_COND (stmt);
     422                 :      294665 :   type = SWITCH_STMT_TYPE (stmt);
     423                 :             : 
     424                 :      294665 :   walk_tree_1 (&cond, func, data, NULL, lh);
     425                 :             : 
     426                 :      294665 :   break_block = begin_bc_block (bc_break, stmt_locus);
     427                 :             : 
     428                 :      294665 :   walk_tree_1 (&body, func, data, NULL, lh);
     429                 :      294665 :   walk_tree_1 (&type, func, data, NULL, lh);
     430                 :      294665 :   *walk_subtrees = 0;
     431                 :             : 
     432                 :      294665 :   if (TREE_USED (break_block))
     433                 :      139350 :     SWITCH_BREAK_LABEL_P (break_block) = 1;
     434                 :      294665 :   finish_bc_block (&body, bc_break, break_block);
     435                 :      294665 :   *stmt_p = build2_loc (stmt_locus, SWITCH_EXPR, type, cond, body);
     436                 :      294665 :   SWITCH_ALL_CASES_P (*stmt_p) = SWITCH_STMT_ALL_CASES_P (stmt);
     437                 :      294665 :   gcc_checking_assert (!SWITCH_STMT_NO_BREAK_P (stmt)
     438                 :             :                        || !TREE_USED (break_block));
     439                 :      294665 : }
     440                 :             : 
     441                 :             : /* Genericize a CONTINUE_STMT node *STMT_P.  */
     442                 :             : 
     443                 :             : static void
     444                 :       22759 : genericize_continue_stmt (tree *stmt_p)
     445                 :             : {
     446                 :       22759 :   tree stmt_list = NULL;
     447                 :       22759 :   tree pred = build_predict_expr (PRED_CONTINUE, NOT_TAKEN);
     448                 :       22759 :   tree label = get_bc_label (bc_continue);
     449                 :       22759 :   location_t location = EXPR_LOCATION (*stmt_p);
     450                 :       22759 :   tree jump = build1_loc (location, GOTO_EXPR, void_type_node, label);
     451                 :       22759 :   append_to_statement_list_force (pred, &stmt_list);
     452                 :       22759 :   append_to_statement_list (jump, &stmt_list);
     453                 :       22759 :   *stmt_p = stmt_list;
     454                 :       22759 : }
     455                 :             : 
     456                 :             : /* Genericize a BREAK_STMT node *STMT_P.  */
     457                 :             : 
     458                 :             : static void
     459                 :     1213772 : genericize_break_stmt (tree *stmt_p)
     460                 :             : {
     461                 :     1213772 :   tree label = get_bc_label (bc_break);
     462                 :     1213772 :   location_t location = EXPR_LOCATION (*stmt_p);
     463                 :     1213772 :   *stmt_p = build1_loc (location, GOTO_EXPR, void_type_node, label);
     464                 :     1213772 : }
     465                 :             : 
     466                 :             : /* Genericize a OMP_FOR node *STMT_P.  */
     467                 :             : 
     468                 :             : static void
     469                 :       41762 : genericize_omp_for_stmt (tree *stmt_p, int *walk_subtrees, void *data,
     470                 :             :                          walk_tree_fn func, walk_tree_lh lh)
     471                 :             : {
     472                 :       41762 :   tree stmt = *stmt_p;
     473                 :       41762 :   location_t locus = EXPR_LOCATION (stmt);
     474                 :       41762 :   tree clab = begin_bc_block (bc_continue, locus);
     475                 :             : 
     476                 :       41762 :   walk_tree_1 (&OMP_FOR_BODY (stmt), func, data, NULL, lh);
     477                 :       41762 :   if (TREE_CODE (stmt) != OMP_TASKLOOP)
     478                 :       40250 :     walk_tree_1 (&OMP_FOR_CLAUSES (stmt), func, data, NULL, lh);
     479                 :       41762 :   walk_tree_1 (&OMP_FOR_INIT (stmt), func, data, NULL, lh);
     480                 :       41762 :   walk_tree_1 (&OMP_FOR_COND (stmt), func, data, NULL, lh);
     481                 :       41762 :   walk_tree_1 (&OMP_FOR_INCR (stmt), func, data, NULL, lh);
     482                 :       41762 :   walk_tree_1 (&OMP_FOR_PRE_BODY (stmt), func, data, NULL, lh);
     483                 :       41762 :   *walk_subtrees = 0;
     484                 :             : 
     485                 :       41762 :   finish_bc_block (&OMP_FOR_BODY (stmt), bc_continue, clab);
     486                 :       41762 : }
     487                 :             : 
     488                 :             : 
     489                 :             : /* Lower structured control flow tree nodes, such as loops.  The
     490                 :             :    STMT_P, WALK_SUBTREES, and DATA arguments are as for the walk_tree_fn
     491                 :             :    type.  FUNC and LH are language-specific functions passed to walk_tree_1
     492                 :             :    for node visiting and traversal, respectively; they are used to do
     493                 :             :    subtree processing in a language-dependent way.  */
     494                 :             : 
     495                 :             : tree
     496                 :   632329648 : c_genericize_control_stmt (tree *stmt_p, int *walk_subtrees, void *data,
     497                 :             :                            walk_tree_fn func, walk_tree_lh lh)
     498                 :             : {
     499                 :   632329648 :   tree stmt = *stmt_p;
     500                 :             : 
     501                 :   632329648 :   switch (TREE_CODE (stmt))
     502                 :             :     {
     503                 :     1514169 :     case FOR_STMT:
     504                 :     1514169 :       genericize_for_stmt (stmt_p, walk_subtrees, data, func, lh);
     505                 :     1514169 :       break;
     506                 :             : 
     507                 :      482868 :     case WHILE_STMT:
     508                 :      482868 :       genericize_while_stmt (stmt_p, walk_subtrees, data, func, lh);
     509                 :      482868 :       break;
     510                 :             : 
     511                 :     1160772 :     case DO_STMT:
     512                 :     1160772 :       genericize_do_stmt (stmt_p, walk_subtrees, data, func, lh);
     513                 :     1160772 :       break;
     514                 :             : 
     515                 :      294665 :     case SWITCH_STMT:
     516                 :      294665 :       genericize_switch_stmt (stmt_p, walk_subtrees, data, func, lh);
     517                 :      294665 :       break;
     518                 :             : 
     519                 :       22759 :     case CONTINUE_STMT:
     520                 :       22759 :       genericize_continue_stmt (stmt_p);
     521                 :       22759 :       break;
     522                 :             : 
     523                 :     1213772 :     case BREAK_STMT:
     524                 :     1213772 :       genericize_break_stmt (stmt_p);
     525                 :     1213772 :       break;
     526                 :             : 
     527                 :       41762 :     case OMP_FOR:
     528                 :       41762 :     case OMP_SIMD:
     529                 :       41762 :     case OMP_DISTRIBUTE:
     530                 :       41762 :     case OMP_LOOP:
     531                 :       41762 :     case OMP_TASKLOOP:
     532                 :       41762 :     case OACC_LOOP:
     533                 :       41762 :       genericize_omp_for_stmt (stmt_p, walk_subtrees, data, func, lh);
     534                 :       41762 :       break;
     535                 :             : 
     536                 :    48713294 :     case STATEMENT_LIST:
     537                 :    48713294 :       if (TREE_SIDE_EFFECTS (stmt))
     538                 :             :         {
     539                 :    46485772 :           tree_stmt_iterator i;
     540                 :    46485772 :           int nondebug_stmts = 0;
     541                 :    46485772 :           bool clear_side_effects = true;
     542                 :             :           /* Genericization can clear TREE_SIDE_EFFECTS, e.g. when
     543                 :             :              transforming an IF_STMT into COND_EXPR.  If such stmt
     544                 :             :              appears in a STATEMENT_LIST that contains only that
     545                 :             :              stmt and some DEBUG_BEGIN_STMTs, without -g where the
     546                 :             :              STATEMENT_LIST wouldn't be present at all the resulting
     547                 :             :              expression wouldn't have TREE_SIDE_EFFECTS set, so make sure
     548                 :             :              to clear it even on the STATEMENT_LIST in such cases.  */
     549                 :    92971544 :           hash_set<tree> *pset = (c_dialect_cxx ()
     550                 :    46485772 :                                   ? nullptr
     551                 :             :                                   : static_cast<hash_set<tree> *>(data));
     552                 :   200636218 :           for (i = tsi_start (stmt); !tsi_end_p (i); tsi_next (&i))
     553                 :             :             {
     554                 :   154150446 :               tree t = tsi_stmt (i);
     555                 :   154150446 :               if (TREE_CODE (t) != DEBUG_BEGIN_STMT && nondebug_stmts < 2)
     556                 :    71947326 :                 nondebug_stmts++;
     557                 :   154150446 :               walk_tree_1 (tsi_stmt_ptr (i), func, data, pset, lh);
     558                 :   154150446 :               if (TREE_CODE (t) != DEBUG_BEGIN_STMT
     559                 :   154150446 :                   && (nondebug_stmts > 1 || TREE_SIDE_EFFECTS (tsi_stmt (i))))
     560                 :             :                 clear_side_effects = false;
     561                 :             :             }
     562                 :    46485772 :           if (clear_side_effects)
     563                 :        2433 :             TREE_SIDE_EFFECTS (stmt) = 0;
     564                 :    46485772 :           *walk_subtrees = 0;
     565                 :             :         }
     566                 :             :       break;
     567                 :             : 
     568                 :             :     default:
     569                 :             :       break;
     570                 :             :     }
     571                 :             : 
     572                 :   632329648 :   return NULL;
     573                 :             : }
     574                 :             : 
     575                 :             : 
     576                 :             : /* Wrapper for c_genericize_control_stmt to allow it to be used as a walk_tree
     577                 :             :    callback.  This is appropriate for C; C++ calls c_genericize_control_stmt
     578                 :             :    directly.  */
     579                 :             : 
     580                 :             : static tree
     581                 :   583019773 : c_genericize_control_r (tree *stmt_p, int *walk_subtrees, void *data)
     582                 :             : {
     583                 :   583019773 :   c_genericize_control_stmt (stmt_p, walk_subtrees, data,
     584                 :             :                              c_genericize_control_r, NULL);
     585                 :   583019773 :   return NULL;
     586                 :             : }
     587                 :             : 
     588                 :             : /* Convert the tree representation of FNDECL from C frontend trees to
     589                 :             :    GENERIC.  */
     590                 :             : 
     591                 :             : void
     592                 :    69610300 : c_genericize (tree fndecl)
     593                 :             : {
     594                 :    69610300 :   dump_file_info *dfi;
     595                 :    69610300 :   FILE *dump_orig;
     596                 :    69610300 :   dump_flags_t local_dump_flags;
     597                 :    69610300 :   struct cgraph_node *cgn;
     598                 :             : 
     599                 :    69610300 :   if (flag_sanitize & SANITIZE_BOUNDS)
     600                 :             :     {
     601                 :       52644 :       hash_set<tree> pset;
     602                 :       52644 :       walk_tree (&DECL_SAVED_TREE (fndecl), ubsan_walk_array_refs_r, &pset,
     603                 :             :                  &pset);
     604                 :       52644 :     }
     605                 :             : 
     606                 :             :   /* Genericize loops and other structured control constructs.  The C++
     607                 :             :      front end has already done this in lang-specific code.  */
     608                 :    69610300 :   if (!c_dialect_cxx ())
     609                 :             :     {
     610                 :    31771492 :       bc_state_t save_state;
     611                 :    31771492 :       push_cfun (DECL_STRUCT_FUNCTION (fndecl));
     612                 :    31771492 :       save_bc_state (&save_state);
     613                 :    31771492 :       hash_set<tree> pset;
     614                 :    31771492 :       walk_tree (&DECL_SAVED_TREE (fndecl), c_genericize_control_r, &pset,
     615                 :             :                  &pset);
     616                 :    31771492 :       restore_bc_state (&save_state);
     617                 :    31771492 :       pop_cfun ();
     618                 :    31771492 :     }
     619                 :             : 
     620                 :    69610300 :   if (warn_duplicated_branches)
     621                 :         163 :     walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
     622                 :             :                                   do_warn_duplicated_branches_r, NULL);
     623                 :             : 
     624                 :             :   /* Dump the C-specific tree IR.  */
     625                 :    69610300 :   dfi = g->get_dumps ()->get_dump_file_info (TDI_original);
     626                 :    69610300 :   dump_orig = dfi->pstream;
     627                 :    69610300 :   local_dump_flags = dfi->pflags;
     628                 :    69610300 :   if (dump_orig)
     629                 :             :     {
     630                 :        1170 :       fprintf (dump_orig, "\n;; Function %s",
     631                 :        1170 :                lang_hooks.decl_printable_name (fndecl, 2));
     632                 :        1170 :       fprintf (dump_orig, " (%s)\n",
     633                 :        1170 :                (!DECL_ASSEMBLER_NAME_SET_P (fndecl) ? "null"
     634                 :           3 :                 : IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl))));
     635                 :        1170 :       fprintf (dump_orig, ";; enabled by -%s\n", dump_flag_name (TDI_original));
     636                 :        1170 :       fprintf (dump_orig, "\n");
     637                 :             : 
     638                 :        1170 :       if (local_dump_flags & TDF_RAW)
     639                 :           1 :         dump_node (DECL_SAVED_TREE (fndecl),
     640                 :             :                    TDF_SLIM | local_dump_flags, dump_orig);
     641                 :             :       else
     642                 :        1169 :         print_c_tree (dump_orig, DECL_SAVED_TREE (fndecl));
     643                 :        1170 :       fprintf (dump_orig, "\n");
     644                 :             :     }
     645                 :             : 
     646                 :             :   /* Dump all nested functions now.  */
     647                 :    69610300 :   cgn = cgraph_node::get_create (fndecl);
     648                 :    69611807 :   for (cgn = first_nested_function (cgn);
     649                 :    69611807 :        cgn; cgn = next_nested_function (cgn))
     650                 :        1507 :     c_genericize (cgn->decl);
     651                 :    69610300 : }
     652                 :             : 
     653                 :             : static void
     654                 :           0 : add_block_to_enclosing (tree block)
     655                 :             : {
     656                 :           0 :   unsigned i;
     657                 :           0 :   tree enclosing;
     658                 :           0 :   gbind *bind;
     659                 :           0 :   vec<gbind *> stack = gimple_bind_expr_stack ();
     660                 :             : 
     661                 :           0 :   FOR_EACH_VEC_ELT (stack, i, bind)
     662                 :           0 :     if (gimple_bind_block (bind))
     663                 :             :       break;
     664                 :             : 
     665                 :           0 :   enclosing = gimple_bind_block (bind);
     666                 :           0 :   BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
     667                 :           0 : }
     668                 :             : 
     669                 :             : /* Genericize a scope by creating a new BIND_EXPR.
     670                 :             :    BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
     671                 :             :      In the latter case, we need to create a new BLOCK and add it to the
     672                 :             :      BLOCK_SUBBLOCKS of the enclosing block.
     673                 :             :    BODY is a chain of C _STMT nodes for the contents of the scope, to be
     674                 :             :      genericized.  */
     675                 :             : 
     676                 :             : tree
     677                 :   121470041 : c_build_bind_expr (location_t loc, tree block, tree body)
     678                 :             : {
     679                 :   121470041 :   tree decls, bind;
     680                 :             : 
     681                 :   121470041 :   if (block == NULL_TREE)
     682                 :             :     decls = NULL_TREE;
     683                 :    52102864 :   else if (TREE_CODE (block) == BLOCK)
     684                 :    52102864 :     decls = BLOCK_VARS (block);
     685                 :             :   else
     686                 :             :     {
     687                 :           0 :       decls = block;
     688                 :           0 :       if (DECL_ARTIFICIAL (decls))
     689                 :             :         block = NULL_TREE;
     690                 :             :       else
     691                 :             :         {
     692                 :           0 :           block = make_node (BLOCK);
     693                 :           0 :           BLOCK_VARS (block) = decls;
     694                 :           0 :           add_block_to_enclosing (block);
     695                 :             :         }
     696                 :             :     }
     697                 :             : 
     698                 :   121470041 :   if (!body)
     699                 :           0 :     body = build_empty_stmt (loc);
     700                 :   121470041 :   if (decls || block)
     701                 :             :     {
     702                 :    52102864 :       bind = build3 (BIND_EXPR, void_type_node, decls, body, block);
     703                 :    52102864 :       TREE_SIDE_EFFECTS (bind) = 1;
     704                 :    52102864 :       SET_EXPR_LOCATION (bind, loc);
     705                 :             :     }
     706                 :             :   else
     707                 :             :     bind = body;
     708                 :             : 
     709                 :   121470041 :   return bind;
     710                 :             : }
     711                 :             : 
     712                 :             : /* Helper for c_gimplify_expr: test if target supports fma-like FN.  */
     713                 :             : 
     714                 :             : static bool
     715                 :           0 : fma_supported_p (enum internal_fn fn, tree type)
     716                 :             : {
     717                 :           0 :   return direct_internal_fn_supported_p (fn, type, OPTIMIZE_FOR_BOTH);
     718                 :             : }
     719                 :             : 
     720                 :             : /* Gimplification of expression trees.  */
     721                 :             : 
     722                 :             : /* Do C-specific gimplification on *EXPR_P.  PRE_P and POST_P are as in
     723                 :             :    gimplify_expr.  */
     724                 :             : 
     725                 :             : int
     726                 :   242819910 : c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
     727                 :             :                  gimple_seq *post_p ATTRIBUTE_UNUSED)
     728                 :             : {
     729                 :   242819910 :   enum tree_code code = TREE_CODE (*expr_p);
     730                 :             : 
     731                 :   242819910 :   switch (code)
     732                 :             :     {
     733                 :      353454 :     case LSHIFT_EXPR:
     734                 :      353454 :     case RSHIFT_EXPR:
     735                 :      353454 :     case LROTATE_EXPR:
     736                 :      353454 :     case RROTATE_EXPR:
     737                 :      353454 :       {
     738                 :             :         /* We used to convert the right operand of a shift-expression
     739                 :             :            to an integer_type_node in the FEs.  But it is unnecessary
     740                 :             :            and not desirable for diagnostics and sanitizers.  We keep
     741                 :             :            this here to not pessimize the code, but we convert to an
     742                 :             :            unsigned type, because negative shift counts are undefined
     743                 :             :            anyway.
     744                 :             :            We should get rid of this conversion when we have a proper
     745                 :             :            type demotion/promotion pass.  */
     746                 :      353454 :         tree *op1_p = &TREE_OPERAND (*expr_p, 1);
     747                 :      353454 :         if (!VECTOR_TYPE_P (TREE_TYPE (*op1_p))
     748                 :      351757 :             && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)),
     749                 :             :                                     unsigned_type_node)
     750                 :      651493 :             && !types_compatible_p (TYPE_MAIN_VARIANT (TREE_TYPE (*op1_p)),
     751                 :             :                                     integer_type_node))
     752                 :             :           /* Make sure to unshare the result, tree sharing is invalid
     753                 :             :              during gimplification.  */
     754                 :       21402 :           *op1_p = unshare_expr (convert (unsigned_type_node, *op1_p));
     755                 :             :         break;
     756                 :             :       }
     757                 :             : 
     758                 :     1100170 :     case PREINCREMENT_EXPR:
     759                 :     1100170 :     case PREDECREMENT_EXPR:
     760                 :     1100170 :     case POSTINCREMENT_EXPR:
     761                 :     1100170 :     case POSTDECREMENT_EXPR:
     762                 :     1100170 :       {
     763                 :     1100170 :         tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
     764                 :     1100170 :         if (INTEGRAL_TYPE_P (type) && c_promoting_integer_type_p (type))
     765                 :             :           {
     766                 :        5705 :             if (!TYPE_OVERFLOW_WRAPS (type))
     767                 :        3199 :               type = unsigned_type_for (type);
     768                 :        5705 :             return gimplify_self_mod_expr (expr_p, pre_p, post_p, 1, type);
     769                 :             :           }
     770                 :             :         break;
     771                 :             :       }
     772                 :             : 
     773                 :     7165490 :     case PLUS_EXPR:
     774                 :     7165490 :     case MINUS_EXPR:
     775                 :     7165490 :       {
     776                 :     7165490 :         tree type = TREE_TYPE (*expr_p);
     777                 :             :         /* For -ffp-contract=on we need to attempt FMA contraction only
     778                 :             :            during initial gimplification.  Late contraction across statement
     779                 :             :            boundaries would violate language semantics.  */
     780                 :     7165490 :         if (SCALAR_FLOAT_TYPE_P (type)
     781                 :      954989 :             && flag_fp_contract_mode == FP_CONTRACT_ON
     782                 :           0 :             && cfun && !(cfun->curr_properties & PROP_gimple_any)
     783                 :     7165490 :             && fma_supported_p (IFN_FMA, type))
     784                 :             :           {
     785                 :           0 :             bool neg_mul = false, neg_add = code == MINUS_EXPR;
     786                 :             : 
     787                 :           0 :             tree *op0_p = &TREE_OPERAND (*expr_p, 0);
     788                 :           0 :             tree *op1_p = &TREE_OPERAND (*expr_p, 1);
     789                 :             : 
     790                 :             :             /* Look for ±(x * y) ± z, swapping operands if necessary.  */
     791                 :           0 :             if (TREE_CODE (*op0_p) == NEGATE_EXPR
     792                 :           0 :                 && TREE_CODE (TREE_OPERAND (*op0_p, 0)) == MULT_EXPR)
     793                 :             :               /* '*EXPR_P' is '-(x * y) ± z'.  This is fine.  */;
     794                 :           0 :             else if (TREE_CODE (*op0_p) != MULT_EXPR)
     795                 :             :               {
     796                 :             :                 std::swap (op0_p, op1_p);
     797                 :             :                 std::swap (neg_mul, neg_add);
     798                 :             :               }
     799                 :           0 :             if (TREE_CODE (*op0_p) == NEGATE_EXPR)
     800                 :             :               {
     801                 :           0 :                 op0_p = &TREE_OPERAND (*op0_p, 0);
     802                 :           0 :                 neg_mul = !neg_mul;
     803                 :             :               }
     804                 :           0 :             if (TREE_CODE (*op0_p) != MULT_EXPR)
     805                 :             :               break;
     806                 :           0 :             auto_vec<tree, 3> ops (3);
     807                 :           0 :             ops.quick_push (TREE_OPERAND (*op0_p, 0));
     808                 :           0 :             ops.quick_push (TREE_OPERAND (*op0_p, 1));
     809                 :           0 :             ops.quick_push (*op1_p);
     810                 :             : 
     811                 :           0 :             enum internal_fn ifn = IFN_FMA;
     812                 :           0 :             if (neg_mul)
     813                 :             :               {
     814                 :           0 :                 if (fma_supported_p (IFN_FNMA, type))
     815                 :             :                   ifn = IFN_FNMA;
     816                 :             :                 else
     817                 :           0 :                   ops[0] = build1 (NEGATE_EXPR, type, ops[0]);
     818                 :             :               }
     819                 :           0 :             if (neg_add)
     820                 :             :               {
     821                 :           0 :                 enum internal_fn ifn2 = ifn == IFN_FMA ? IFN_FMS : IFN_FNMS;
     822                 :           0 :                 if (fma_supported_p (ifn2, type))
     823                 :             :                   ifn = ifn2;
     824                 :             :                 else
     825                 :           0 :                   ops[2] = build1 (NEGATE_EXPR, type, ops[2]);
     826                 :             :               }
     827                 :             :             /* Avoid gimplify_arg: it emits all side effects into *PRE_P.  */
     828                 :           0 :             for (auto &&op : ops)
     829                 :           0 :               if (gimplify_expr (&op, pre_p, post_p, is_gimple_val, fb_rvalue)
     830                 :             :                   == GS_ERROR)
     831                 :             :                 return GS_ERROR;
     832                 :             : 
     833                 :           0 :             gcall *call = gimple_build_call_internal_vec (ifn, ops);
     834                 :           0 :             gimple_seq_add_stmt_without_update (pre_p, call);
     835                 :           0 :             *expr_p = create_tmp_var (type);
     836                 :           0 :             gimple_call_set_lhs (call, *expr_p);
     837                 :           0 :             return GS_ALL_DONE;
     838                 :           0 :           }
     839                 :             :         break;
     840                 :             :       }
     841                 :             : 
     842                 :     3651636 :     case CALL_EXPR:
     843                 :     3651636 :       {
     844                 :     3651636 :         tree fndecl = get_callee_fndecl (*expr_p);
     845                 :     3651636 :         if (fndecl
     846                 :     3421238 :             && fndecl_built_in_p (fndecl, BUILT_IN_CLZG, BUILT_IN_CTZG)
     847                 :          61 :             && call_expr_nargs (*expr_p) == 2
     848                 :     3651697 :             && TREE_CODE (CALL_EXPR_ARG (*expr_p, 1)) != INTEGER_CST)
     849                 :             :           {
     850                 :          61 :             tree a = save_expr (CALL_EXPR_ARG (*expr_p, 0));
     851                 :          61 :             tree c = build_call_expr_loc (EXPR_LOCATION (*expr_p),
     852                 :             :                                           fndecl, 1, a);
     853                 :         122 :             *expr_p = build3_loc (EXPR_LOCATION (*expr_p), COND_EXPR,
     854                 :             :                                   integer_type_node,
     855                 :          61 :                                   build2_loc (EXPR_LOCATION (*expr_p),
     856                 :             :                                               NE_EXPR, boolean_type_node, a,
     857                 :          61 :                                               build_zero_cst (TREE_TYPE (a))),
     858                 :          61 :                                   c, CALL_EXPR_ARG (*expr_p, 1));
     859                 :          61 :             return GS_OK;
     860                 :             :           }
     861                 :             :         break;
     862                 :             :       }
     863                 :             : 
     864                 :             :     default:;
     865                 :             :     }
     866                 :             : 
     867                 :             :   return GS_UNHANDLED;
     868                 :             : }
        

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.