LCOV - code coverage report
Current view: top level - gcc - tree-cfg.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 82.9 % 5164 4280
Test Date: 2026-08-22 16:33:35 Functions: 90.9 % 209 190
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Control flow functions for trees.
       2              :    Copyright (C) 2001-2026 Free Software Foundation, Inc.
       3              :    Contributed by Diego Novillo <dnovillo@redhat.com>
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify
       8              : it under the terms of the GNU General Public License as published by
       9              : the Free Software Foundation; either version 3, or (at your option)
      10              : any later version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful,
      13              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      14              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15              : GNU General Public License for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : #include "config.h"
      22              : #include "system.h"
      23              : #include "coretypes.h"
      24              : #include "backend.h"
      25              : #include "target.h"
      26              : #include "rtl.h"
      27              : #include "tree.h"
      28              : #include "gimple.h"
      29              : #include "cfghooks.h"
      30              : #include "tree-pass.h"
      31              : #include "ssa.h"
      32              : #include "cgraph.h"
      33              : #include "gimple-pretty-print.h"
      34              : #include "diagnostic-core.h"
      35              : #include "fold-const.h"
      36              : #include "trans-mem.h"
      37              : #include "stor-layout.h"
      38              : #include "print-tree.h"
      39              : #include "cfganal.h"
      40              : #include "gimple-iterator.h"
      41              : #include "gimple-fold.h"
      42              : #include "tree-eh.h"
      43              : #include "gimplify-me.h"
      44              : #include "gimple-walk.h"
      45              : #include "tree-cfg.h"
      46              : #include "tree-ssa-loop-manip.h"
      47              : #include "tree-ssa-loop-niter.h"
      48              : #include "tree-into-ssa.h"
      49              : #include "tree-dfa.h"
      50              : #include "tree-ssa.h"
      51              : #include "except.h"
      52              : #include "cfgloop.h"
      53              : #include "tree-ssa-propagate.h"
      54              : #include "value-prof.h"
      55              : #include "tree-inline.h"
      56              : #include "tree-ssa-live.h"
      57              : #include "tree-ssa-dce.h"
      58              : #include "omp-general.h"
      59              : #include "omp-expand.h"
      60              : #include "tree-cfgcleanup.h"
      61              : #include "gimplify.h"
      62              : #include "attribs.h"
      63              : #include "selftest.h"
      64              : #include "opts.h"
      65              : #include "asan.h"
      66              : #include "profile.h"
      67              : #include "sreal.h"
      68              : #include "gcc-urlifier.h"
      69              : 
      70              : /* This file contains functions for building the Control Flow Graph (CFG)
      71              :    for a function tree.  */
      72              : 
      73              : /* Local declarations.  */
      74              : 
      75              : /* Initial capacity for the basic block array.  */
      76              : static const int initial_cfg_capacity = 20;
      77              : 
      78              : /* This hash table allows us to efficiently lookup all CASE_LABEL_EXPRs
      79              :    which use a particular edge.  The CASE_LABEL_EXPRs are chained together
      80              :    via their CASE_CHAIN field, which we clear after we're done with the
      81              :    hash table to prevent problems with duplication of GIMPLE_SWITCHes.
      82              : 
      83              :    Access to this list of CASE_LABEL_EXPRs allows us to efficiently
      84              :    update the case vector in response to edge redirections.
      85              : 
      86              :    Right now this table is set up and torn down at key points in the
      87              :    compilation process.  It would be nice if we could make the table
      88              :    more persistent.  The key is getting notification of changes to
      89              :    the CFG (particularly edge removal, creation and redirection).  */
      90              : 
      91              : static hash_map<edge, tree> *edge_to_cases;
      92              : 
      93              : /* If we record edge_to_cases, this bitmap will hold indexes
      94              :    of basic blocks that end in a GIMPLE_SWITCH which we touched
      95              :    due to edge manipulations.  */
      96              : 
      97              : static bitmap touched_switch_bbs;
      98              : 
      99              : /* OpenMP region idxs for blocks during cfg pass.  */
     100              : static vec<int> bb_to_omp_idx;
     101              : 
     102              : /* CFG statistics.  */
     103              : struct cfg_stats_d
     104              : {
     105              :   long num_merged_labels;
     106              : };
     107              : 
     108              : static struct cfg_stats_d cfg_stats;
     109              : 
     110              : /* Data to pass to replace_block_vars_by_duplicates_1.  */
     111              : struct replace_decls_d
     112              : {
     113              :   hash_map<tree, tree> *vars_map;
     114              :   tree to_context;
     115              : };
     116              : 
     117              : /* Basic blocks and flowgraphs.  */
     118              : static void make_blocks (gimple_seq);
     119              : 
     120              : /* Edges.  */
     121              : static void make_edges (void);
     122              : static void assign_discriminators (void);
     123              : static void make_cond_expr_edges (basic_block);
     124              : static void make_gimple_switch_edges (gswitch *, basic_block);
     125              : static bool make_goto_expr_edges (basic_block);
     126              : static void make_gimple_asm_edges (basic_block);
     127              : static edge gimple_redirect_edge_and_branch (edge, basic_block);
     128              : static edge gimple_try_redirect_by_replacing_jump (edge, basic_block);
     129              : 
     130              : /* Various helpers.  */
     131              : static inline bool stmt_starts_bb_p (gimple *, gimple *);
     132              : static bool gimple_verify_flow_info (void);
     133              : static void gimple_make_forwarder_block (edge);
     134              : static bool verify_gimple_transaction (gtransaction *);
     135              : static bool call_can_make_abnormal_goto (gimple *);
     136              : static bool gimple_empty_block_p (basic_block);
     137              : 
     138              : /* Flowgraph optimization and cleanup.  */
     139              : static void gimple_merge_blocks (basic_block, basic_block);
     140              : static bool gimple_can_merge_blocks_p (basic_block, basic_block);
     141              : static void remove_bb (basic_block);
     142              : static edge find_taken_edge_computed_goto (basic_block, tree);
     143              : static edge find_taken_edge_cond_expr (const gcond *, tree);
     144              : 
     145              : void
     146      3432164 : init_empty_tree_cfg_for_function (struct function *fn)
     147              : {
     148              :   /* Initialize the basic block array.  */
     149      3432164 :   init_flow (fn);
     150      3432164 :   profile_status_for_fn (fn) = PROFILE_ABSENT;
     151      3432164 :   n_basic_blocks_for_fn (fn) = NUM_FIXED_BLOCKS;
     152      3432164 :   last_basic_block_for_fn (fn) = NUM_FIXED_BLOCKS;
     153      3432164 :   vec_safe_grow_cleared (basic_block_info_for_fn (fn),
     154              :                          initial_cfg_capacity, true);
     155              : 
     156              :   /* Build a mapping of labels to their associated blocks.  */
     157      3432164 :   vec_safe_grow_cleared (label_to_block_map_for_fn (fn),
     158              :                          initial_cfg_capacity, true);
     159              : 
     160      3432164 :   SET_BASIC_BLOCK_FOR_FN (fn, ENTRY_BLOCK, ENTRY_BLOCK_PTR_FOR_FN (fn));
     161      3432164 :   SET_BASIC_BLOCK_FOR_FN (fn, EXIT_BLOCK, EXIT_BLOCK_PTR_FOR_FN (fn));
     162              : 
     163      3432164 :   ENTRY_BLOCK_PTR_FOR_FN (fn)->next_bb
     164      3432164 :     = EXIT_BLOCK_PTR_FOR_FN (fn);
     165      3432164 :   EXIT_BLOCK_PTR_FOR_FN (fn)->prev_bb
     166      3432164 :     = ENTRY_BLOCK_PTR_FOR_FN (fn);
     167      3432164 : }
     168              : 
     169              : void
     170      3347860 : init_empty_tree_cfg (void)
     171              : {
     172      3347860 :   init_empty_tree_cfg_for_function (cfun);
     173      3347860 : }
     174              : 
     175              : /*---------------------------------------------------------------------------
     176              :                               Create basic blocks
     177              : ---------------------------------------------------------------------------*/
     178              : 
     179              : /* Entry point to the CFG builder for trees.  SEQ is the sequence of
     180              :    statements to be added to the flowgraph.  */
     181              : 
     182              : static void
     183      3027087 : build_gimple_cfg (gimple_seq seq)
     184              : {
     185              :   /* Register specific gimple functions.  */
     186      3027087 :   gimple_register_cfg_hooks ();
     187              : 
     188      3027087 :   memset ((void *) &cfg_stats, 0, sizeof (cfg_stats));
     189              : 
     190      3027087 :   init_empty_tree_cfg ();
     191              : 
     192      3027087 :   make_blocks (seq);
     193              : 
     194              :   /* Make sure there is always at least one block, even if it's empty.  */
     195      3027087 :   if (n_basic_blocks_for_fn (cfun) == NUM_FIXED_BLOCKS)
     196            0 :     create_empty_bb (ENTRY_BLOCK_PTR_FOR_FN (cfun));
     197              : 
     198              :   /* Adjust the size of the array.  */
     199      3027087 :   if (basic_block_info_for_fn (cfun)->length ()
     200      3027087 :       < (size_t) n_basic_blocks_for_fn (cfun))
     201            0 :     vec_safe_grow_cleared (basic_block_info_for_fn (cfun),
     202              :                            n_basic_blocks_for_fn (cfun));
     203              : 
     204              :   /* To speed up statement iterator walks, we first purge dead labels.  */
     205      3027087 :   cleanup_dead_labels ();
     206              : 
     207              :   /* Group case nodes to reduce the number of edges.
     208              :      We do this after cleaning up dead labels because otherwise we miss
     209              :      a lot of obvious case merging opportunities.  */
     210      3027087 :   group_case_labels ();
     211              : 
     212              :   /* Create the edges of the flowgraph.  */
     213      3027087 :   make_edges ();
     214      3027087 :   assign_discriminators ();
     215      3027087 :   cleanup_dead_labels ();
     216      3027087 : }
     217              : 
     218              : /* Look for ANNOTATE calls with loop annotation kind in BB; if found, remove
     219              :    them and propagate the information to LOOP.  We assume that the annotations
     220              :    come immediately before the condition in BB, if any.  */
     221              : 
     222              : static void
     223      1579592 : replace_loop_annotate_in_block (basic_block bb, class loop *loop)
     224              : {
     225      1579592 :   gimple_stmt_iterator gsi = gsi_last_bb (bb);
     226      1579592 :   gimple *stmt = gsi_stmt (gsi);
     227              : 
     228      1579592 :   if (!(stmt && gimple_code (stmt) == GIMPLE_COND))
     229       582936 :     return;
     230              : 
     231      1002297 :   for (gsi_prev_nondebug (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
     232              :     {
     233       547563 :       stmt = gsi_stmt (gsi);
     234       547563 :       if (gimple_code (stmt) != GIMPLE_CALL)
     235              :         break;
     236        57500 :       if (!gimple_call_internal_p (stmt)
     237        57500 :           || gimple_call_internal_fn (stmt) != IFN_ANNOTATE)
     238              :         break;
     239              : 
     240         5586 :       switch ((annot_expr_kind) tree_to_shwi (gimple_call_arg (stmt, 1)))
     241              :         {
     242          352 :         case annot_expr_ivdep_kind:
     243          352 :           loop->safelen = INT_MAX;
     244          352 :           break;
     245         2069 :         case annot_expr_unroll_kind:
     246         2069 :           loop->unroll
     247         2069 :             = (unsigned short) tree_to_shwi (gimple_call_arg (stmt, 2));
     248         2069 :           cfun->has_unroll = true;
     249         2069 :           break;
     250         3098 :         case annot_expr_no_vector_kind:
     251         3098 :           loop->dont_vectorize = true;
     252         3098 :           break;
     253            3 :         case annot_expr_vector_kind:
     254            3 :           loop->force_vectorize = true;
     255            3 :           cfun->has_force_vectorize_loops = true;
     256            3 :           break;
     257            0 :         case annot_expr_parallel_kind:
     258            0 :           loop->can_be_parallel = true;
     259            0 :           loop->safelen = INT_MAX;
     260            0 :           break;
     261           64 :         case annot_expr_maybe_infinite_kind:
     262           64 :           loop->finite_p = false;
     263           64 :           break;
     264            0 :         default:
     265            0 :           gcc_unreachable ();
     266              :         }
     267              : 
     268         5586 :       stmt = gimple_build_assign (gimple_call_lhs (stmt),
     269              :                                   gimple_call_arg (stmt, 0));
     270         5586 :       gsi_replace (&gsi, stmt, true);
     271              :     }
     272              : }
     273              : 
     274              : /* Look for ANNOTATE calls with loop annotation kind; if found, remove
     275              :    them and propagate the information to the loop.  We assume that the
     276              :    annotations come immediately before the condition of the loop.  */
     277              : 
     278              : static void
     279      3027087 : replace_loop_annotate (void)
     280              : {
     281      3027087 :   basic_block bb;
     282      3027087 :   gimple_stmt_iterator gsi;
     283      3027087 :   gimple *stmt;
     284              : 
     285      9710636 :   for (auto loop : loops_list (cfun, 0))
     286              :     {
     287              :       /* Push the global flag_finite_loops state down to individual loops.  */
     288       629375 :       loop->finite_p = flag_finite_loops;
     289              : 
     290              :       /* Check all exit source blocks for annotations.  */
     291      3458749 :       for (auto e : get_loop_exit_edges (loop))
     292      2208967 :         replace_loop_annotate_in_block (e->src, loop);
     293      3027087 :     }
     294              : 
     295              :   /* Remove IFN_ANNOTATE.  Safeguard for the case loop->latch == NULL.  */
     296     21159367 :   FOR_EACH_BB_FN (bb, cfun)
     297              :     {
     298    122370192 :       for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
     299              :         {
     300     68061696 :           stmt = gsi_stmt (gsi);
     301     68061696 :           if (gimple_code (stmt) != GIMPLE_CALL)
     302     57353647 :             continue;
     303     10708049 :           if (!gimple_call_internal_p (stmt)
     304     10708049 :               || gimple_call_internal_fn (stmt) != IFN_ANNOTATE)
     305     10708049 :             continue;
     306              : 
     307            0 :           switch ((annot_expr_kind) tree_to_shwi (gimple_call_arg (stmt, 1)))
     308              :             {
     309            0 :             case annot_expr_ivdep_kind:
     310            0 :             case annot_expr_unroll_kind:
     311            0 :             case annot_expr_no_vector_kind:
     312            0 :             case annot_expr_vector_kind:
     313            0 :             case annot_expr_parallel_kind:
     314            0 :             case annot_expr_maybe_infinite_kind:
     315            0 :               break;
     316            0 :             default:
     317            0 :               gcc_unreachable ();
     318              :             }
     319              : 
     320            0 :           warning_at (gimple_location (stmt), 0, "ignoring loop annotation");
     321            0 :           stmt = gimple_build_assign (gimple_call_lhs (stmt),
     322              :                                       gimple_call_arg (stmt, 0));
     323            0 :           gsi_replace (&gsi, stmt, true);
     324              :         }
     325              :     }
     326      3027087 : }
     327              : 
     328              : static unsigned int
     329      3027087 : execute_build_cfg (void)
     330              : {
     331      3027087 :   gimple_seq body = gimple_body (current_function_decl);
     332              : 
     333      3027087 :   build_gimple_cfg (body);
     334      3027087 :   gimple_set_body (current_function_decl, NULL);
     335      3027087 :   if (dump_file && (dump_flags & TDF_DETAILS))
     336              :     {
     337            2 :       fprintf (dump_file, "Scope blocks:\n");
     338            2 :       dump_scope_blocks (dump_file, dump_flags);
     339              :     }
     340      3027087 :   cleanup_tree_cfg ();
     341              : 
     342      3027087 :   bb_to_omp_idx.release ();
     343              : 
     344      3027087 :   loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
     345      3027087 :   replace_loop_annotate ();
     346      3027087 :   return 0;
     347              : }
     348              : 
     349              : namespace {
     350              : 
     351              : const pass_data pass_data_build_cfg =
     352              : {
     353              :   GIMPLE_PASS, /* type */
     354              :   "cfg", /* name */
     355              :   OPTGROUP_NONE, /* optinfo_flags */
     356              :   TV_TREE_CFG, /* tv_id */
     357              :   PROP_gimple_leh, /* properties_required */
     358              :   ( PROP_cfg | PROP_loops ), /* properties_provided */
     359              :   0, /* properties_destroyed */
     360              :   0, /* todo_flags_start */
     361              :   0, /* todo_flags_finish */
     362              : };
     363              : 
     364              : class pass_build_cfg : public gimple_opt_pass
     365              : {
     366              : public:
     367       294212 :   pass_build_cfg (gcc::context *ctxt)
     368       588424 :     : gimple_opt_pass (pass_data_build_cfg, ctxt)
     369              :   {}
     370              : 
     371              :   /* opt_pass methods: */
     372      3027087 :   unsigned int execute (function *) final override
     373              :   {
     374      3027087 :     return execute_build_cfg ();
     375              :   }
     376              : 
     377              : }; // class pass_build_cfg
     378              : 
     379              : } // anon namespace
     380              : 
     381              : gimple_opt_pass *
     382       294212 : make_pass_build_cfg (gcc::context *ctxt)
     383              : {
     384       294212 :   return new pass_build_cfg (ctxt);
     385              : }
     386              : 
     387              : 
     388              : /* Return true if T is a computed goto.  */
     389              : 
     390              : bool
     391    690530562 : computed_goto_p (gimple *t)
     392              : {
     393    690530562 :   return (gimple_code (t) == GIMPLE_GOTO
     394    690530562 :           && TREE_CODE (gimple_goto_dest (t)) != LABEL_DECL);
     395              : }
     396              : 
     397              : /* Returns true if the sequence of statements STMTS only contains
     398              :    a call to __builtin_unreachable ().  */
     399              : 
     400              : bool
     401      3797611 : gimple_seq_unreachable_p (gimple_seq stmts)
     402              : {
     403      3797611 :   if (stmts == NULL
     404              :       /* Return false if -fsanitize=unreachable, we don't want to
     405              :          optimize away those calls, but rather turn them into
     406              :          __ubsan_handle_builtin_unreachable () or __builtin_trap ()
     407              :          later.  */
     408      3797611 :       || sanitize_flags_p (SANITIZE_UNREACHABLE))
     409              :     return false;
     410              : 
     411      3794930 :   gimple_stmt_iterator gsi = gsi_last (stmts);
     412              : 
     413      3794930 :   if (!gimple_call_builtin_p (gsi_stmt (gsi), BUILT_IN_UNREACHABLE))
     414              :     return false;
     415              : 
     416      1224974 :   for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
     417              :     {
     418         6980 :       gimple *stmt = gsi_stmt (gsi);
     419         6980 :       if (gimple_code (stmt) != GIMPLE_LABEL
     420         4350 :           && !is_gimple_debug (stmt)
     421         8070 :           && !gimple_clobber_p (stmt))
     422              :       return false;
     423              :     }
     424              :   return true;
     425              : }
     426              : 
     427              : /* Returns true for edge E where e->src ends with a GIMPLE_COND and
     428              :    the other edge points to a bb with just __builtin_unreachable ().
     429              :    I.e. return true for C->M edge in:
     430              :    <bb C>:
     431              :    ...
     432              :    if (something)
     433              :      goto <bb N>;
     434              :    else
     435              :      goto <bb M>;
     436              :    <bb N>:
     437              :    __builtin_unreachable ();
     438              :    <bb M>:  */
     439              : 
     440              : bool
     441     12413624 : assert_unreachable_fallthru_edge_p (edge e)
     442              : {
     443     12413624 :   basic_block pred_bb = e->src;
     444     24827248 :   if (safe_is_a <gcond *> (*gsi_last_bb (pred_bb)))
     445              :     {
     446     12413624 :       basic_block other_bb = EDGE_SUCC (pred_bb, 0)->dest;
     447     12413624 :       if (other_bb == e->dest)
     448      6576044 :         other_bb = EDGE_SUCC (pred_bb, 1)->dest;
     449     12413624 :       if (EDGE_COUNT (other_bb->succs) == 0)
     450      3782750 :         return gimple_seq_unreachable_p (bb_seq (other_bb));
     451              :     }
     452              :   return false;
     453              : }
     454              : 
     455              : 
     456              : /* Initialize GF_CALL_CTRL_ALTERING flag, which indicates the call
     457              :    could alter control flow except via eh. We initialize the flag at
     458              :    CFG build time and only ever clear it later.  */
     459              : 
     460              : static void
     461     11405275 : gimple_call_initialize_ctrl_altering (gimple *stmt)
     462              : {
     463     11405275 :   int flags = gimple_call_flags (stmt);
     464              : 
     465              :   /* A call alters control flow if it can make an abnormal goto.  */
     466     11405275 :   if (call_can_make_abnormal_goto (stmt)
     467              :       /* A call also alters control flow if it does not return.  */
     468     11398004 :       || flags & ECF_NORETURN
     469              :       /* TM ending statements have backedges out of the transaction.
     470              :          Return true so we split the basic block containing them.
     471              :          Note that the TM_BUILTIN test is merely an optimization.  */
     472      9719163 :       || ((flags & ECF_TM_BUILTIN)
     473          985 :           && is_tm_ending_fndecl (gimple_call_fndecl (stmt)))
     474              :       /* BUILT_IN_RETURN call is same as return statement.  */
     475      9718185 :       || gimple_call_builtin_p (stmt, BUILT_IN_RETURN)
     476              :       /* IFN_UNIQUE should be the last insn, to make checking for it
     477              :          as cheap as possible.  */
     478     21123460 :       || (gimple_call_internal_p (stmt)
     479       523865 :           && gimple_call_internal_unique_p (stmt)))
     480      1772883 :     gimple_call_set_ctrl_altering (stmt, true);
     481              :   else
     482      9632392 :     gimple_call_set_ctrl_altering (stmt, false);
     483     11405275 : }
     484              : 
     485              : 
     486              : /* Insert SEQ after BB and build a flowgraph.  */
     487              : 
     488              : static basic_block
     489      3079453 : make_blocks_1 (gimple_seq seq, basic_block bb)
     490              : {
     491      3079453 :   gimple_stmt_iterator i = gsi_start (seq);
     492      3079453 :   gimple *stmt = NULL;
     493      3079453 :   gimple *prev_stmt = NULL;
     494      3079453 :   bool start_new_block = true;
     495      3079453 :   bool first_stmt_of_seq = true;
     496      3079453 :   bool suppress_coverage_p = false;
     497              : 
     498     96745133 :   while (!gsi_end_p (i))
     499              :     {
     500              :       /* PREV_STMT should only be set to a debug stmt if the debug
     501              :          stmt is before nondebug stmts.  Once stmt reaches a nondebug
     502              :          nonlabel, prev_stmt will be set to it, so that
     503              :          stmt_starts_bb_p will know to start a new block if a label is
     504              :          found.  However, if stmt was a label after debug stmts only,
     505              :          keep the label in prev_stmt even if we find further debug
     506              :          stmts, for there may be other labels after them, and they
     507              :          should land in the same block.  */
     508     93665680 :       if (!prev_stmt || !stmt || !is_gimple_debug (stmt))
     509              :         prev_stmt = stmt;
     510     93665680 :       stmt = gsi_stmt (i);
     511              : 
     512     93665680 :       if (stmt && is_gimple_call (stmt))
     513     11405275 :         gimple_call_initialize_ctrl_altering (stmt);
     514              : 
     515     93665680 :       suppress_coverage_p = in_pragma_suppress_coverage_p (stmt,
     516              :                                                            suppress_coverage_p);
     517     93665680 :       if (suppress_coverage_p && !coverage_suppressed_p (bb))
     518              :         start_new_block = true;
     519     93665318 :       else if (!suppress_coverage_p && coverage_suppressed_p (bb))
     520              :         start_new_block = true;
     521              : 
     522              :       /* If the statement starts a new basic block or if we have determined
     523              :          in a previous pass that we need to create a new block for STMT, do
     524              :          so now.  */
     525     93664988 :       if (start_new_block || stmt_starts_bb_p (stmt, prev_stmt))
     526              :         {
     527     22412741 :           if (!first_stmt_of_seq)
     528     19333288 :             gsi_split_seq_before (&i, &seq);
     529     22412741 :           bb = create_basic_block (seq, bb);
     530              : 
     531     22412741 :           start_new_block = false;
     532     22412741 :           prev_stmt = NULL;
     533              :         }
     534              : 
     535              :       /* Now add STMT to BB and create the subgraphs for special statement
     536              :          codes.  */
     537     93665680 :       gimple_set_bb (stmt, bb);
     538              : 
     539     93665680 :       if (suppress_coverage_p)
     540         2075 :         suppress_coverage (bb);
     541              : 
     542              :       /* If STMT is a basic block terminator, set START_NEW_BLOCK for the
     543              :          next iteration.  */
     544     93665680 :       if (stmt_ends_bb_p (stmt))
     545              :         {
     546              :           /* If the stmt can make abnormal goto use a new temporary
     547              :              for the assignment to the LHS.  This makes sure the old value
     548              :              of the LHS is available on the abnormal edge.  Otherwise
     549              :              we will end up with overlapping life-ranges for abnormal
     550              :              SSA names.  */
     551     20438973 :           if (gimple_has_lhs (stmt)
     552      1658018 :               && stmt_can_make_abnormal_goto (stmt)
     553      3588760 :               && is_gimple_reg_type (TREE_TYPE (gimple_get_lhs (stmt))))
     554              :             {
     555         2502 :               tree lhs = gimple_get_lhs (stmt);
     556         2502 :               tree tmp = create_tmp_var (TREE_TYPE (lhs));
     557         2502 :               gimple *s = gimple_build_assign (lhs, tmp);
     558         2502 :               gimple_set_location (s, gimple_location (stmt));
     559         2502 :               gimple_set_block (s, gimple_block (stmt));
     560         2502 :               gimple_set_lhs (stmt, tmp);
     561         2502 :               gsi_insert_after (&i, s, GSI_SAME_STMT);
     562              :             }
     563              :           start_new_block = true;
     564              :         }
     565              : 
     566     93665680 :       gsi_next (&i);
     567     93665680 :       first_stmt_of_seq = false;
     568              :     }
     569      3079453 :   return bb;
     570              : }
     571              : 
     572              : /* Build a flowgraph for the sequence of stmts SEQ.  */
     573              : 
     574              : static void
     575      3027087 : make_blocks (gimple_seq seq)
     576              : {
     577              :   /* Look for debug markers right before labels, and move the debug
     578              :      stmts after the labels.  Accepting labels among debug markers
     579              :      adds no value, just complexity; if we wanted to annotate labels
     580              :      with view numbers (so sequencing among markers would matter) or
     581              :      somesuch, we're probably better off still moving the labels, but
     582              :      adding other debug annotations in their original positions or
     583              :      emitting nonbind or bind markers associated with the labels in
     584              :      the original position of the labels.
     585              : 
     586              :      Moving labels would probably be simpler, but we can't do that:
     587              :      moving labels assigns label ids to them, and doing so because of
     588              :      debug markers makes for -fcompare-debug and possibly even codegen
     589              :      differences.  So, we have to move the debug stmts instead.  To
     590              :      that end, we scan SEQ backwards, marking the position of the
     591              :      latest (earliest we find) label, and moving debug stmts that are
     592              :      not separated from it by nondebug nonlabel stmts after the
     593              :      label.  */
     594      3027087 :   if (MAY_HAVE_DEBUG_MARKER_STMTS)
     595              :     {
     596      1879161 :       gimple_stmt_iterator label = gsi_none ();
     597              : 
     598     56049844 :       for (gimple_stmt_iterator i = gsi_last (seq); !gsi_end_p (i); gsi_prev (&i))
     599              :         {
     600     50412361 :           gimple *stmt = gsi_stmt (i);
     601              : 
     602              :           /* If this is the first label we encounter (latest in SEQ)
     603              :              before nondebug stmts, record its position.  */
     604     50412361 :           if (is_a <glabel *> (stmt))
     605              :             {
     606      9485772 :               if (gsi_end_p (label))
     607      8814981 :                 label = i;
     608      9485772 :               continue;
     609              :             }
     610              : 
     611              :           /* Without a recorded label position to move debug stmts to,
     612              :              there's nothing to do.  */
     613     40926589 :           if (gsi_end_p (label))
     614     32093097 :             continue;
     615              : 
     616              :           /* Move the debug stmt at I after LABEL.  */
     617      8833492 :           if (is_gimple_debug (stmt))
     618              :             {
     619        23814 :               gcc_assert (gimple_debug_nonbind_marker_p (stmt));
     620              :               /* As STMT is removed, I advances to the stmt after
     621              :                  STMT, so the gsi_prev in the for "increment"
     622              :                  expression gets us to the stmt we're to visit after
     623              :                  STMT.  LABEL, however, would advance to the moved
     624              :                  stmt if we passed it to gsi_move_after, so pass it a
     625              :                  copy instead, so as to keep LABEL pointing to the
     626              :                  LABEL.  */
     627        23814 :               gimple_stmt_iterator copy = label;
     628        23814 :               gsi_move_after (&i, &copy);
     629        23814 :               continue;
     630        23814 :             }
     631              : 
     632              :           /* There aren't any (more?) debug stmts before label, so
     633              :              there isn't anything else to move after it.  */
     634              :           label = gsi_none ();
     635              :         }
     636              :     }
     637              : 
     638              :   /* If the function decl itself is in a #pragma GCC suppress_coverage block we
     639              :      insert a nop with the same location as the function so that we're
     640              :      guaranteed that the first block gets coverage suppressed and the function
     641              :      entry isn't counted.
     642              : 
     643              :      #pragma GCC suppress_coverage begin
     644              :      int foo (args) // count = suppressed
     645              :      {
     646              :      #pragma GCC suppress_coverage end
     647              :        ...
     648              :      }
     649              : 
     650              :      If it isn't and the first stmt is suppressed we insert a nop to ensure that
     651              :      the function entry is counted, but the first (real) stmt is not:
     652              : 
     653              :      int foo (args) // count = 1
     654              :      {
     655              :      #pragma GCC suppress_coverage begin
     656              :        bar (); // count = suppressed
     657              :      #pragma GCC suppress_coverage end
     658              :        ...
     659              :      }
     660              : 
     661              :      gimple_can_merge_blocks_p is aware of specific instruction.  */
     662      3027087 :   gimple_stmt_iterator gsi = gsi_start (seq);
     663      3027087 :   const location_t decl_loc = DECL_SOURCE_LOCATION (cfun->decl);
     664      3027087 :   if (location_in_pragma_suppress_coverage_p (decl_loc))
     665              :     {
     666           31 :       gimple *nop = gimple_build_nop ();
     667           31 :       gimple_set_location (nop, decl_loc);
     668           31 :       gsi_insert_seq_before (&gsi, nop, GSI_NEW_STMT);
     669              :     }
     670      3027056 :   else if (*gsi && in_pragma_suppress_coverage_p (*gsi, false))
     671              :     {
     672          101 :       gimple *nop = gimple_build_nop ();
     673          101 :       gsi_insert_seq_before (&gsi, nop, GSI_NEW_STMT);
     674              :     }
     675              : 
     676      3027087 :   make_blocks_1 (seq, ENTRY_BLOCK_PTR_FOR_FN (cfun));
     677      3027087 : }
     678              : 
     679              : /* Create and return a new empty basic block after bb AFTER.  */
     680              : 
     681              : static basic_block
     682     73141494 : create_bb (void *h, void *e, basic_block after)
     683              : {
     684     73141494 :   basic_block bb;
     685              : 
     686     73141494 :   gcc_assert (!e);
     687              : 
     688              :   /* Create and initialize a new basic block.  Since alloc_block uses
     689              :      GC allocation that clears memory to allocate a basic block, we do
     690              :      not have to clear the newly allocated basic block here.  */
     691     73141494 :   bb = alloc_block ();
     692              : 
     693     73141494 :   bb->index = last_basic_block_for_fn (cfun);
     694     73141494 :   bb->flags = BB_NEW;
     695     73141494 :   set_bb_seq (bb, h ? (gimple_seq) h : NULL);
     696              : 
     697              :   /* Add the new block to the linked list of blocks.  */
     698     73141494 :   link_block (bb, after);
     699              : 
     700              :   /* Grow the basic block array if needed.  */
     701     73141494 :   if ((size_t) last_basic_block_for_fn (cfun)
     702     73141494 :       == basic_block_info_for_fn (cfun)->length ())
     703     22418008 :     vec_safe_grow_cleared (basic_block_info_for_fn (cfun),
     704     22418008 :                            last_basic_block_for_fn (cfun) + 1);
     705              : 
     706              :   /* Add the newly created block to the array.  */
     707     73141494 :   SET_BASIC_BLOCK_FOR_FN (cfun, last_basic_block_for_fn (cfun), bb);
     708              : 
     709     73141494 :   n_basic_blocks_for_fn (cfun)++;
     710     73141494 :   last_basic_block_for_fn (cfun)++;
     711              : 
     712     73141494 :   return bb;
     713              : }
     714              : 
     715              : 
     716              : /*---------------------------------------------------------------------------
     717              :                                  Edge creation
     718              : ---------------------------------------------------------------------------*/
     719              : 
     720              : /* If basic block BB has an abnormal edge to a basic block
     721              :    containing IFN_ABNORMAL_DISPATCHER internal call, return
     722              :    that the dispatcher's basic block, otherwise return NULL.  */
     723              : 
     724              : basic_block
     725          661 : get_abnormal_succ_dispatcher (basic_block bb)
     726              : {
     727          661 :   edge e;
     728          661 :   edge_iterator ei;
     729              : 
     730         1403 :   FOR_EACH_EDGE (e, ei, bb->succs)
     731         1053 :     if ((e->flags & (EDGE_ABNORMAL | EDGE_EH)) == EDGE_ABNORMAL)
     732              :       {
     733          311 :         gimple_stmt_iterator gsi
     734          311 :           = gsi_start_nondebug_after_labels_bb (e->dest);
     735          311 :         gimple *g = gsi_stmt (gsi);
     736          311 :         if (g && gimple_call_internal_p (g, IFN_ABNORMAL_DISPATCHER))
     737          311 :           return e->dest;
     738              :       }
     739              :   return NULL;
     740              : }
     741              : 
     742              : /* Helper function for make_edges.  Create a basic block with
     743              :    with ABNORMAL_DISPATCHER internal call in it if needed, and
     744              :    create abnormal edges from BBS to it and from it to FOR_BB
     745              :    if COMPUTED_GOTO is false, otherwise factor the computed gotos.  */
     746              : 
     747              : static void
     748         5297 : handle_abnormal_edges (basic_block *dispatcher_bbs, basic_block for_bb,
     749              :                        auto_vec<basic_block> *bbs, bool computed_goto)
     750              : {
     751         5297 :   basic_block *dispatcher = dispatcher_bbs + (computed_goto ? 1 : 0);
     752         5297 :   unsigned int idx = 0;
     753         5297 :   basic_block bb;
     754         5297 :   bool inner = false;
     755              : 
     756         5297 :   if (!bb_to_omp_idx.is_empty ())
     757              :     {
     758           11 :       dispatcher = dispatcher_bbs + 2 * bb_to_omp_idx[for_bb->index];
     759           11 :       if (bb_to_omp_idx[for_bb->index] != 0)
     760            6 :         inner = true;
     761              :     }
     762              : 
     763              :   /* If the dispatcher has been created already, then there are basic
     764              :      blocks with abnormal edges to it, so just make a new edge to
     765              :      for_bb.  */
     766         5297 :   if (*dispatcher == NULL)
     767              :     {
     768              :       /* Check if there are any basic blocks that need to have
     769              :          abnormal edges to this dispatcher.  If there are none, return
     770              :          early.  */
     771         3502 :       if (bb_to_omp_idx.is_empty ())
     772              :         {
     773         3491 :           if (bbs->is_empty ())
     774         5297 :             return;
     775              :         }
     776              :       else
     777              :         {
     778           18 :           FOR_EACH_VEC_ELT (*bbs, idx, bb)
     779           18 :             if (bb_to_omp_idx[bb->index] == bb_to_omp_idx[for_bb->index])
     780              :               break;
     781           11 :           if (bb == NULL)
     782              :             return;
     783              :         }
     784              : 
     785              :       /* Create the dispatcher bb.  */
     786         2675 :       *dispatcher = create_basic_block (NULL, for_bb);
     787         2675 :       if (computed_goto)
     788              :         {
     789              :           /* Factor computed gotos into a common computed goto site.  Also
     790              :              record the location of that site so that we can un-factor the
     791              :              gotos after we have converted back to normal form.  */
     792          563 :           gimple_stmt_iterator gsi = gsi_start_bb (*dispatcher);
     793              : 
     794              :           /* Create the destination of the factored goto.  Each original
     795              :              computed goto will put its desired destination into this
     796              :              variable and jump to the label we create immediately below.  */
     797          563 :           tree var = create_tmp_var (ptr_type_node, "gotovar");
     798              : 
     799              :           /* Build a label for the new block which will contain the
     800              :              factored computed goto.  */
     801          563 :           tree factored_label_decl
     802          563 :             = create_artificial_label (UNKNOWN_LOCATION);
     803          563 :           gimple *factored_computed_goto_label
     804          563 :             = gimple_build_label (factored_label_decl);
     805          563 :           gsi_insert_after (&gsi, factored_computed_goto_label, GSI_NEW_STMT);
     806              : 
     807              :           /* Build our new computed goto.  */
     808          563 :           gimple *factored_computed_goto = gimple_build_goto (var);
     809          563 :           gsi_insert_after (&gsi, factored_computed_goto, GSI_NEW_STMT);
     810              : 
     811         2722 :           FOR_EACH_VEC_ELT (*bbs, idx, bb)
     812              :             {
     813         1033 :               if (!bb_to_omp_idx.is_empty ()
     814            0 :                   && bb_to_omp_idx[bb->index] != bb_to_omp_idx[for_bb->index])
     815            0 :                 continue;
     816              : 
     817         1033 :               gsi = gsi_last_bb (bb);
     818         1033 :               gimple *last = gsi_stmt (gsi);
     819              : 
     820         1033 :               gcc_assert (computed_goto_p (last));
     821              : 
     822              :               /* Copy the original computed goto's destination into VAR.  */
     823         1033 :               gimple *assignment
     824         1033 :                 = gimple_build_assign (var, gimple_goto_dest (last));
     825         1033 :               gsi_insert_before (&gsi, assignment, GSI_SAME_STMT);
     826              : 
     827         1033 :               edge e = make_edge (bb, *dispatcher, EDGE_FALLTHRU);
     828         1033 :               e->goto_locus = gimple_location (last);
     829         1033 :               gsi_remove (&gsi, true);
     830              :             }
     831              :         }
     832              :       else
     833              :         {
     834         2112 :           tree arg = inner ? boolean_true_node : boolean_false_node;
     835         2112 :           gcall *g = gimple_build_call_internal (IFN_ABNORMAL_DISPATCHER,
     836              :                                                  1, arg);
     837         2112 :           gimple_call_set_ctrl_altering (g, true);
     838         2112 :           gimple_stmt_iterator gsi = gsi_after_labels (*dispatcher);
     839         2112 :           gsi_insert_after (&gsi, g, GSI_NEW_STMT);
     840              : 
     841              :           /* Create predecessor edges of the dispatcher.  */
     842        13615 :           FOR_EACH_VEC_ELT (*bbs, idx, bb)
     843              :             {
     844         7279 :               if (!bb_to_omp_idx.is_empty ()
     845           44 :                   && bb_to_omp_idx[bb->index] != bb_to_omp_idx[for_bb->index])
     846           20 :                 continue;
     847         7259 :               make_edge (bb, *dispatcher, EDGE_ABNORMAL);
     848              :             }
     849              :         }
     850              :     }
     851              : 
     852         4470 :   make_edge (*dispatcher, for_bb, EDGE_ABNORMAL);
     853              : }
     854              : 
     855              : /* Creates outgoing edges for BB.  Returns 1 when it ends with an
     856              :    computed goto, returns 2 when it ends with a statement that
     857              :    might return to this function via an nonlocal goto, otherwise
     858              :    return 0.  Updates *PCUR_REGION with the OMP region this BB is in.  */
     859              : 
     860              : static int
     861     22412741 : make_edges_bb (basic_block bb, struct omp_region **pcur_region, int *pomp_index)
     862              : {
     863     22412741 :   gimple *last = *gsi_last_bb (bb);
     864     22412741 :   bool fallthru = false;
     865     22412741 :   int ret = 0;
     866              : 
     867     22412741 :   if (!last)
     868              :     return ret;
     869              : 
     870     22412741 :   switch (gimple_code (last))
     871              :     {
     872      6308470 :     case GIMPLE_GOTO:
     873      6308470 :       if (make_goto_expr_edges (bb))
     874              :         ret = 1;
     875              :       fallthru = false;
     876              :       break;
     877      3017404 :     case GIMPLE_RETURN:
     878      3017404 :       {
     879      3017404 :         edge e = make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
     880      3017404 :         e->goto_locus = gimple_location (last);
     881      3017404 :         fallthru = false;
     882              :       }
     883      3017404 :       break;
     884      5569462 :     case GIMPLE_COND:
     885      5569462 :       make_cond_expr_edges (bb);
     886      5569462 :       fallthru = false;
     887      5569462 :       break;
     888        53774 :     case GIMPLE_SWITCH:
     889        53774 :       make_gimple_switch_edges (as_a <gswitch *> (last), bb);
     890        53774 :       fallthru = false;
     891        53774 :       break;
     892       949741 :     case GIMPLE_RESX:
     893       949741 :       make_eh_edge (last);
     894       949741 :       fallthru = false;
     895       949741 :       break;
     896        42777 :     case GIMPLE_EH_DISPATCH:
     897        42777 :       fallthru = make_eh_dispatch_edges (as_a <geh_dispatch *> (last));
     898        42777 :       break;
     899              : 
     900      3929195 :     case GIMPLE_CALL:
     901              :       /* If this function receives a nonlocal goto, then we need to
     902              :          make edges from this call site to all the nonlocal goto
     903              :          handlers.  */
     904      3929195 :       if (stmt_can_make_abnormal_goto (last))
     905         7271 :         ret = 2;
     906              : 
     907              :       /* If this statement has reachable exception handlers, then
     908              :          create abnormal edges to them.  */
     909      3929195 :       make_eh_edge (last);
     910              : 
     911              :       /* BUILTIN_RETURN is really a return statement.  */
     912      3929195 :       if (gimple_call_builtin_p (last, BUILT_IN_RETURN))
     913              :         {
     914          368 :           make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
     915          368 :           fallthru = false;
     916              :         }
     917              :       /* Some calls are known not to return.  */
     918              :       else
     919      3928827 :         fallthru = !gimple_call_noreturn_p (last);
     920              :       break;
     921              : 
     922      2230904 :     case GIMPLE_ASSIGN:
     923              :       /* A GIMPLE_ASSIGN may throw internally and thus be considered
     924              :          control-altering.  */
     925      2230904 :       if (is_ctrl_altering_stmt (last))
     926       618538 :         make_eh_edge (last);
     927              :       fallthru = true;
     928              :       break;
     929              : 
     930         1616 :     case GIMPLE_ASM:
     931         1616 :       make_gimple_asm_edges (bb);
     932         1616 :       fallthru = true;
     933         1616 :       break;
     934              : 
     935       291622 :     CASE_GIMPLE_OMP:
     936       291622 :       fallthru = omp_make_gimple_edges (bb, pcur_region, pomp_index);
     937       291622 :       break;
     938              : 
     939          411 :     case GIMPLE_TRANSACTION:
     940          411 :       {
     941          411 :         gtransaction *txn = as_a <gtransaction *> (last);
     942          411 :         tree label1 = gimple_transaction_label_norm (txn);
     943          411 :         tree label2 = gimple_transaction_label_uninst (txn);
     944              : 
     945          411 :         if (label1)
     946          401 :           make_edge (bb, label_to_block (cfun, label1), EDGE_FALLTHRU);
     947          411 :         if (label2)
     948          397 :           make_edge (bb, label_to_block (cfun, label2),
     949          397 :                      EDGE_TM_UNINSTRUMENTED | (label1 ? 0 : EDGE_FALLTHRU));
     950              : 
     951          411 :         tree label3 = gimple_transaction_label_over (txn);
     952          411 :         if (gimple_transaction_subcode (txn)
     953              :             & (GTMA_HAVE_ABORT | GTMA_IS_OUTER))
     954           65 :           make_edge (bb, label_to_block (cfun, label3), EDGE_TM_ABORT);
     955              : 
     956              :         fallthru = false;
     957              :       }
     958              :       break;
     959              : 
     960        17365 :     default:
     961        17365 :       gcc_assert (!stmt_ends_bb_p (last));
     962              :       fallthru = true;
     963              :       break;
     964              :     }
     965              : 
     966     14474194 :   if (fallthru)
     967      4746853 :     make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
     968              : 
     969              :   return ret;
     970              : }
     971              : 
     972              : /* Join all the blocks in the flowgraph.  */
     973              : 
     974              : static void
     975      3027087 : make_edges (void)
     976              : {
     977      3027087 :   basic_block bb;
     978      3027087 :   struct omp_region *cur_region = NULL;
     979      3027087 :   auto_vec<basic_block> ab_edge_goto;
     980      3027087 :   auto_vec<basic_block> ab_edge_call;
     981      3027087 :   int cur_omp_region_idx = 0;
     982              : 
     983              :   /* Create an edge from entry to the first block with executable
     984              :      statements in it.  */
     985      3027087 :   make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun),
     986      3027087 :              BASIC_BLOCK_FOR_FN (cfun, NUM_FIXED_BLOCKS),
     987              :              EDGE_FALLTHRU);
     988              : 
     989              :   /* Traverse the basic block array placing edges.  */
     990     25300162 :   FOR_EACH_BB_FN (bb, cfun)
     991              :     {
     992     22273075 :       int mer;
     993              : 
     994     22273075 :       if (!bb_to_omp_idx.is_empty ())
     995       729667 :         bb_to_omp_idx[bb->index] = cur_omp_region_idx;
     996              : 
     997     22273075 :       mer = make_edges_bb (bb, &cur_region, &cur_omp_region_idx);
     998     22273075 :       if (mer == 1)
     999         1134 :         ab_edge_goto.safe_push (bb);
    1000     22271941 :       else if (mer == 2)
    1001         7271 :         ab_edge_call.safe_push (bb);
    1002              : 
    1003     22811715 :       if (cur_region && bb_to_omp_idx.is_empty ())
    1004        22455 :         bb_to_omp_idx.safe_grow_cleared (n_basic_blocks_for_fn (cfun), true);
    1005              :     }
    1006              : 
    1007              :   /* Computed gotos are hell to deal with, especially if there are
    1008              :      lots of them with a large number of destinations.  So we factor
    1009              :      them to a common computed goto location before we build the
    1010              :      edge list.  After we convert back to normal form, we will un-factor
    1011              :      the computed gotos since factoring introduces an unwanted jump.
    1012              :      For non-local gotos and abnormal edges from calls to calls that return
    1013              :      twice or forced labels, factor the abnormal edges too, by having all
    1014              :      abnormal edges from the calls go to a common artificial basic block
    1015              :      with ABNORMAL_DISPATCHER internal call and abnormal edges from that
    1016              :      basic block to all forced labels and calls returning twice.
    1017              :      We do this per-OpenMP structured block, because those regions
    1018              :      are guaranteed to be single entry single exit by the standard,
    1019              :      so it is not allowed to enter or exit such regions abnormally this way,
    1020              :      thus all computed gotos, non-local gotos and setjmp/longjmp calls
    1021              :      must not transfer control across SESE region boundaries.  */
    1022      3027087 :   if (!ab_edge_goto.is_empty () || !ab_edge_call.is_empty ())
    1023              :     {
    1024         2727 :       gimple_stmt_iterator gsi;
    1025         2727 :       basic_block dispatcher_bb_array[2] = { NULL, NULL };
    1026         2727 :       basic_block *dispatcher_bbs = dispatcher_bb_array;
    1027         2727 :       int count = n_basic_blocks_for_fn (cfun);
    1028              : 
    1029         2727 :       if (!bb_to_omp_idx.is_empty ())
    1030            9 :         dispatcher_bbs = XCNEWVEC (basic_block, 2 * count);
    1031              : 
    1032        31836 :       FOR_EACH_BB_FN (bb, cfun)
    1033              :         {
    1034        74042 :           for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    1035              :             {
    1036        43167 :               glabel *label_stmt = dyn_cast <glabel *> (gsi_stmt (gsi));
    1037        16303 :               tree target;
    1038              : 
    1039        16303 :               if (!label_stmt)
    1040              :                 break;
    1041              : 
    1042        16303 :               target = gimple_label_label (label_stmt);
    1043              : 
    1044              :               /* Make an edge to every label block that has been marked as a
    1045              :                  potential target for a computed goto or a non-local goto.  */
    1046        16303 :               if (FORCED_LABEL (target))
    1047         2434 :                 handle_abnormal_edges (dispatcher_bbs, bb, &ab_edge_goto,
    1048              :                                        true);
    1049        16303 :               if (DECL_NONLOCAL (target))
    1050              :                 {
    1051          479 :                   handle_abnormal_edges (dispatcher_bbs, bb, &ab_edge_call,
    1052              :                                          false);
    1053          479 :                   break;
    1054              :                 }
    1055              :             }
    1056              : 
    1057        29109 :           if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
    1058         2332 :             gsi_next_nondebug (&gsi);
    1059        29109 :           if (!gsi_end_p (gsi))
    1060              :             {
    1061              :               /* Make an edge to every setjmp-like call.  */
    1062        27207 :               gimple *call_stmt = gsi_stmt (gsi);
    1063        27207 :               if (is_gimple_call (call_stmt)
    1064        27207 :                   && ((gimple_call_flags (call_stmt) & ECF_RETURNS_TWICE)
    1065         8291 :                       || gimple_call_builtin_p (call_stmt,
    1066              :                                                 BUILT_IN_SETJMP_RECEIVER)))
    1067         2384 :                 handle_abnormal_edges (dispatcher_bbs, bb, &ab_edge_call,
    1068              :                                        false);
    1069              :             }
    1070              :         }
    1071              : 
    1072         2736 :       if (!bb_to_omp_idx.is_empty ())
    1073            9 :         XDELETE (dispatcher_bbs);
    1074              :     }
    1075              : 
    1076      3027087 :   omp_free_regions ();
    1077      3027087 : }
    1078              : 
    1079              : /* Add SEQ after GSI.  Start new bb after GSI, and created further bbs as
    1080              :    needed.  Returns true if new bbs were created.
    1081              :    Note: This is transitional code, and should not be used for new code.  We
    1082              :    should be able to get rid of this by rewriting all target va-arg
    1083              :    gimplification hooks to use an interface gimple_build_cond_value as described
    1084              :    in https://gcc.gnu.org/ml/gcc-patches/2015-02/msg01194.html.  */
    1085              : 
    1086              : bool
    1087        52366 : gimple_find_sub_bbs (gimple_seq seq, gimple_stmt_iterator *gsi)
    1088              : {
    1089        52366 :   gimple *stmt = gsi_stmt (*gsi);
    1090        52366 :   basic_block bb = gimple_bb (stmt);
    1091        52366 :   basic_block lastbb, afterbb;
    1092        52366 :   int old_num_bbs = n_basic_blocks_for_fn (cfun);
    1093        52366 :   edge e;
    1094        52366 :   lastbb = make_blocks_1 (seq, bb);
    1095        52366 :   if (old_num_bbs == n_basic_blocks_for_fn (cfun))
    1096              :     return false;
    1097        52366 :   e = split_block (bb, stmt);
    1098              :   /* Move e->dest to come after the new basic blocks.  */
    1099        52366 :   afterbb = e->dest;
    1100        52366 :   unlink_block (afterbb);
    1101        52366 :   link_block (afterbb, lastbb);
    1102        52366 :   redirect_edge_succ (e, bb->next_bb);
    1103        52366 :   bb = bb->next_bb;
    1104       192032 :   while (bb != afterbb)
    1105              :     {
    1106       139666 :       struct omp_region *cur_region = NULL;
    1107       139666 :       profile_count cnt = profile_count::zero ();
    1108       139666 :       bool all = true;
    1109              : 
    1110       139666 :       int cur_omp_region_idx = 0;
    1111       139666 :       int mer = make_edges_bb (bb, &cur_region, &cur_omp_region_idx);
    1112       139666 :       gcc_assert (!mer && !cur_region);
    1113       139666 :       add_bb_to_loop (bb, afterbb->loop_father);
    1114              : 
    1115       139666 :       edge e;
    1116       139666 :       edge_iterator ei;
    1117       308691 :       FOR_EACH_EDGE (e, ei, bb->preds)
    1118              :         {
    1119       169025 :           if (e->count ().initialized_p ())
    1120        23557 :             cnt += e->count ();
    1121              :           else
    1122              :             all = false;
    1123              :         }
    1124       139666 :       tree_guess_outgoing_edge_probabilities (bb);
    1125       139666 :       if (all || profile_status_for_fn (cfun) == PROFILE_READ)
    1126        18906 :         bb->count = cnt;
    1127              : 
    1128       139666 :       bb = bb->next_bb;
    1129              :     }
    1130              :   return true;
    1131              : }
    1132              : 
    1133              : /* Auto-profile needs discriminator to distinguish statements with same line
    1134              :    number (file name is ignored) which are in different basic block.  This
    1135              :    map keeps track of current discriminator for a given line number.  */
    1136              : struct discrim_entry
    1137              : {
    1138              :   /* ID of basic block we saw line number last time.  */
    1139              :   unsigned int bb_id;
    1140              :   /* Discriminator we used.  */
    1141              :   unsigned int discrim;
    1142              : };
    1143              : 
    1144              : /* Return updated LOC with discriminator for use in basic block BB_ID.
    1145              :    MAP keeps track of current values.  */
    1146              : 
    1147              : location_t
    1148     75503604 : assign_discriminator (location_t loc, unsigned int bb_id,
    1149              :                       hash_map<int_hash <unsigned, -1U, -2U>,
    1150              :                                discrim_entry> &map)
    1151              : {
    1152     75503604 :   bool existed;
    1153     75503604 :   if ((unsigned) LOCATION_LINE (loc) >= -2U)
    1154              :     return loc;
    1155     75503602 :   discrim_entry &e
    1156     75503602 :     = map.get_or_insert ((unsigned) LOCATION_LINE (loc), &existed);
    1157     75503602 :   gcc_checking_assert (!has_discriminator (loc));
    1158     75503602 :   if (!existed)
    1159              :     {
    1160     14237335 :       e.bb_id = bb_id;
    1161     14237335 :       e.discrim = 0;
    1162     14237335 :       return loc;
    1163              :     }
    1164     61266267 :   if (e.bb_id != bb_id)
    1165              :     {
    1166     41084357 :       e.bb_id = bb_id;
    1167     41084357 :       e.discrim++;
    1168              :     }
    1169     61266267 :   if (e.discrim)
    1170     51922108 :     return location_with_discriminator (loc, e.discrim);
    1171              :   return loc;
    1172              : }
    1173              : 
    1174              : /* Assign discriminators to statement locations.  */
    1175              : 
    1176              : static void
    1177      3027087 : assign_discriminators (void)
    1178              : {
    1179      3027087 :   hash_map<int_hash <unsigned, -1U, -2U>, discrim_entry> map (13);
    1180      3027087 :   unsigned int bb_id = 0;
    1181      3027087 :   basic_block bb;
    1182     25302837 :   FOR_EACH_BB_FN (bb, cfun)
    1183              :     {
    1184     22275750 :       location_t prev_loc = UNKNOWN_LOCATION, prev_replacement = UNKNOWN_LOCATION;
    1185              :       /* Traverse the basic block, if two function calls within a basic block
    1186              :          are mapped to the same line, assign a new discriminator because a call
    1187              :          stmt could be a split point of a basic block.  */
    1188     44551500 :       for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
    1189    106687656 :            !gsi_end_p (gsi); gsi_next (&gsi))
    1190              :         {
    1191     84411906 :           gimple *stmt = gsi_stmt (gsi);
    1192     84411906 :           location_t loc = gimple_location (stmt);
    1193     84411906 :           if (loc == UNKNOWN_LOCATION)
    1194      4648639 :             continue;
    1195     79763267 :           if (loc == prev_loc)
    1196     23767765 :             gimple_set_location (stmt, prev_replacement);
    1197              :           else
    1198              :             {
    1199     55995502 :               prev_loc = loc;
    1200     55995502 :               prev_replacement = assign_discriminator (loc, bb_id, map);
    1201    111991004 :               gimple_set_location (stmt, prev_replacement);
    1202              :             }
    1203              :           /* Break basic blocks after each call.  This is required so each
    1204              :              call site has unique discriminator.
    1205              :              More correctly, we can break after each statement that can possibly
    1206              :              terinate execution of the basic block, but for auto-profile this
    1207              :              precision is probably not useful.  */
    1208     79763267 :           if (gimple_code (stmt) == GIMPLE_CALL)
    1209              :             {
    1210     11403728 :               prev_loc = UNKNOWN_LOCATION;
    1211     11403728 :               bb_id++;
    1212              :             }
    1213              :         }
    1214              :       /* If basic block has multiple successors, consider every edge as a
    1215              :          separate block.  */
    1216     22275750 :       if (!single_succ_p (bb))
    1217      9963702 :         bb_id++;
    1218     91920996 :       for (edge e : bb->succs)
    1219              :         {
    1220     28756178 :           if (e->goto_locus != UNKNOWN_LOCATION)
    1221     19508102 :             e->goto_locus = assign_discriminator (e->goto_locus, bb_id, map);
    1222     28756178 :           for (gphi_iterator gpi = gsi_start_phis (bb);
    1223     28756178 :                !gsi_end_p (gpi); gsi_next (&gpi))
    1224              :             {
    1225            0 :               gphi *phi = gpi.phi ();
    1226            0 :               location_t phi_loc
    1227            0 :                 = gimple_phi_arg_location_from_edge (phi, e);
    1228            0 :               if (phi_loc == UNKNOWN_LOCATION)
    1229            0 :                 continue;
    1230            0 :               gimple_phi_arg_set_location
    1231            0 :                 (phi, e->dest_idx, assign_discriminator (phi_loc, bb_id, map));
    1232              :             }
    1233     28756178 :            bb_id++;
    1234              :         }
    1235     22275750 :       bb_id++;
    1236              :     }
    1237              : 
    1238      3027087 : }
    1239              : 
    1240              : /* Create the edges for a GIMPLE_COND starting at block BB.  */
    1241              : 
    1242              : static void
    1243      5569462 : make_cond_expr_edges (basic_block bb)
    1244              : {
    1245     11138924 :   gcond *entry = as_a <gcond *> (*gsi_last_bb (bb));
    1246      5569462 :   gimple *then_stmt, *else_stmt;
    1247      5569462 :   basic_block then_bb, else_bb;
    1248      5569462 :   tree then_label, else_label;
    1249      5569462 :   edge e;
    1250              : 
    1251      5569462 :   gcc_assert (entry);
    1252              : 
    1253              :   /* Entry basic blocks for each component.  */
    1254      5569462 :   then_label = gimple_cond_true_label (entry);
    1255      5569462 :   else_label = gimple_cond_false_label (entry);
    1256      5569462 :   then_bb = label_to_block (cfun, then_label);
    1257      5569462 :   else_bb = label_to_block (cfun, else_label);
    1258      5569462 :   then_stmt = first_stmt (then_bb);
    1259      5569462 :   else_stmt = first_stmt (else_bb);
    1260              : 
    1261      5569462 :   e = make_edge (bb, then_bb, EDGE_TRUE_VALUE);
    1262      5569462 :   e->goto_locus = gimple_location (then_stmt);
    1263      5569462 :   e = make_edge (bb, else_bb, EDGE_FALSE_VALUE);
    1264      5569462 :   if (e)
    1265      5564113 :     e->goto_locus = gimple_location (else_stmt);
    1266              : 
    1267              :   /* We do not need the labels anymore.  */
    1268      5569462 :   gimple_cond_set_true_label (entry, NULL_TREE);
    1269      5569462 :   gimple_cond_set_false_label (entry, NULL_TREE);
    1270      5569462 : }
    1271              : 
    1272              : 
    1273              : /* Called for each element in the hash table (P) as we delete the
    1274              :    edge to cases hash table.
    1275              : 
    1276              :    Clear all the CASE_CHAINs to prevent problems with copying of
    1277              :    SWITCH_EXPRs and structure sharing rules, then free the hash table
    1278              :    element.  */
    1279              : 
    1280              : bool
    1281      1088325 : edge_to_cases_cleanup (edge const &, tree const &value, void *)
    1282              : {
    1283      1088325 :   tree t, next;
    1284              : 
    1285      2326225 :   for (t = value; t; t = next)
    1286              :     {
    1287      1237900 :       next = CASE_CHAIN (t);
    1288      1237900 :       CASE_CHAIN (t) = NULL;
    1289              :     }
    1290              : 
    1291      1088325 :   return true;
    1292              : }
    1293              : 
    1294              : /* Start recording information mapping edges to case labels.  */
    1295              : 
    1296              : void
    1297     30521676 : start_recording_case_labels (void)
    1298              : {
    1299     30521676 :   gcc_assert (edge_to_cases == NULL);
    1300     30521676 :   edge_to_cases = new hash_map<edge, tree>;
    1301     30521676 :   touched_switch_bbs = BITMAP_ALLOC (NULL);
    1302     30521676 : }
    1303              : 
    1304              : /* Return nonzero if we are recording information for case labels.  */
    1305              : 
    1306              : static bool
    1307       385482 : recording_case_labels_p (void)
    1308              : {
    1309       385482 :   return (edge_to_cases != NULL);
    1310              : }
    1311              : 
    1312              : /* Stop recording information mapping edges to case labels and
    1313              :    remove any information we have recorded.  */
    1314              : void
    1315     30521676 : end_recording_case_labels (void)
    1316              : {
    1317     30521676 :   bitmap_iterator bi;
    1318     30521676 :   unsigned i;
    1319     31610001 :   edge_to_cases->traverse<void *, edge_to_cases_cleanup> (NULL);
    1320     61043352 :   delete edge_to_cases;
    1321     30521676 :   edge_to_cases = NULL;
    1322     30685691 :   EXECUTE_IF_SET_IN_BITMAP (touched_switch_bbs, 0, i, bi)
    1323              :     {
    1324       164015 :       basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
    1325       164015 :       if (bb)
    1326              :         {
    1327       488273 :           if (gswitch *stmt = safe_dyn_cast <gswitch *> (*gsi_last_bb (bb)))
    1328       161917 :             group_case_labels_stmt (stmt);
    1329              :         }
    1330              :     }
    1331     30521676 :   BITMAP_FREE (touched_switch_bbs);
    1332     30521676 : }
    1333              : 
    1334              : /* If we are inside a {start,end}_recording_cases block, then return
    1335              :    a chain of CASE_LABEL_EXPRs from T which reference E.
    1336              : 
    1337              :    Otherwise return NULL.  */
    1338              : 
    1339              : tree
    1340       385482 : get_cases_for_edge (edge e, gswitch *t)
    1341              : {
    1342       385482 :   tree *slot;
    1343       385482 :   size_t i, n;
    1344              : 
    1345              :   /* If we are not recording cases, then we do not have CASE_LABEL_EXPR
    1346              :      chains available.  Return NULL so the caller can detect this case.  */
    1347       385482 :   if (!recording_case_labels_p ())
    1348              :     return NULL;
    1349              : 
    1350       334658 :   slot = edge_to_cases->get (e);
    1351       334658 :   if (slot)
    1352       170755 :     return *slot;
    1353              : 
    1354              :   /* If we did not find E in the hash table, then this must be the first
    1355              :      time we have been queried for information about E & T.  Add all the
    1356              :      elements from T to the hash table then perform the query again.  */
    1357              : 
    1358       163903 :   n = gimple_switch_num_labels (t);
    1359      1393174 :   for (i = 0; i < n; i++)
    1360              :     {
    1361      1229271 :       tree elt = gimple_switch_label (t, i);
    1362      1229271 :       tree lab = CASE_LABEL (elt);
    1363      1229271 :       basic_block label_bb = label_to_block (cfun, lab);
    1364      1229271 :       edge this_edge = find_edge (e->src, label_bb);
    1365              : 
    1366              :       /* Add it to the chain of CASE_LABEL_EXPRs referencing E, or create
    1367              :          a new chain.  */
    1368      1229271 :       tree &s = edge_to_cases->get_or_insert (this_edge);
    1369      1229271 :       CASE_CHAIN (elt) = s;
    1370      1229271 :       s = elt;
    1371              :     }
    1372              : 
    1373       163903 :   return *edge_to_cases->get (e);
    1374              : }
    1375              : 
    1376              : /* Create the edges for a GIMPLE_SWITCH starting at block BB.  */
    1377              : 
    1378              : static void
    1379        53774 : make_gimple_switch_edges (gswitch *entry, basic_block bb)
    1380              : {
    1381        53774 :   size_t i, n;
    1382              : 
    1383        53774 :   n = gimple_switch_num_labels (entry);
    1384              : 
    1385       377029 :   for (i = 0; i < n; ++i)
    1386              :     {
    1387       323255 :       basic_block label_bb = gimple_switch_label_bb (cfun, entry, i);
    1388       323255 :       make_edge (bb, label_bb, 0);
    1389              :     }
    1390        53774 : }
    1391              : 
    1392              : 
    1393              : /* Return the basic block holding label DEST.  */
    1394              : 
    1395              : basic_block
    1396    466263709 : label_to_block (struct function *ifun, tree dest)
    1397              : {
    1398    466263709 :   int uid = LABEL_DECL_UID (dest);
    1399              : 
    1400              :   /* We would die hard when faced by an undefined label.  Emit a label to
    1401              :      the very first basic block.  This will hopefully make even the dataflow
    1402              :      and undefined variable warnings quite right.  */
    1403    466263709 :   if (seen_error () && uid < 0)
    1404              :     {
    1405           97 :       gimple_stmt_iterator gsi =
    1406           97 :         gsi_start_bb (BASIC_BLOCK_FOR_FN (cfun, NUM_FIXED_BLOCKS));
    1407           97 :       gimple *stmt;
    1408              : 
    1409           97 :       stmt = gimple_build_label (dest);
    1410           97 :       gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
    1411           97 :       uid = LABEL_DECL_UID (dest);
    1412              :     }
    1413    466263709 :   if (vec_safe_length (ifun->cfg->x_label_to_block_map) <= (unsigned int) uid)
    1414              :     return NULL;
    1415    466263709 :   return (*ifun->cfg->x_label_to_block_map)[uid];
    1416              : }
    1417              : 
    1418              : /* Create edges for a goto statement at block BB.  Returns true
    1419              :    if abnormal edges should be created.  */
    1420              : 
    1421              : static bool
    1422      6308470 : make_goto_expr_edges (basic_block bb)
    1423              : {
    1424      6308470 :   gimple_stmt_iterator last = gsi_last_bb (bb);
    1425      6308470 :   gimple *goto_t = gsi_stmt (last);
    1426              : 
    1427              :   /* A simple GOTO creates normal edges.  */
    1428      6308470 :   if (simple_goto_p (goto_t))
    1429              :     {
    1430      6307336 :       tree dest = gimple_goto_dest (goto_t);
    1431      6307336 :       basic_block label_bb = label_to_block (cfun, dest);
    1432      6307336 :       edge e = make_edge (bb, label_bb, EDGE_FALLTHRU);
    1433      6307336 :       e->goto_locus = gimple_location (goto_t);
    1434      6307336 :       gsi_remove (&last, true);
    1435      6307336 :       return false;
    1436              :     }
    1437              : 
    1438              :   /* A computed GOTO creates abnormal edges.  */
    1439              :   return true;
    1440              : }
    1441              : 
    1442              : /* Create edges for an asm statement with labels at block BB.  */
    1443              : 
    1444              : static void
    1445         1616 : make_gimple_asm_edges (basic_block bb)
    1446              : {
    1447         3232 :   gasm *stmt = as_a <gasm *> (*gsi_last_bb (bb));
    1448         1616 :   int i, n = gimple_asm_nlabels (stmt);
    1449              : 
    1450         2542 :   for (i = 0; i < n; ++i)
    1451              :     {
    1452          926 :       tree label = TREE_VALUE (gimple_asm_label_op (stmt, i));
    1453          926 :       basic_block label_bb = label_to_block (cfun, label);
    1454          926 :       make_edge (bb, label_bb, 0);
    1455              :     }
    1456         1616 : }
    1457              : 
    1458              : /*---------------------------------------------------------------------------
    1459              :                                Flowgraph analysis
    1460              : ---------------------------------------------------------------------------*/
    1461              : 
    1462              : /* Cleanup useless labels in basic blocks.  This is something we wish
    1463              :    to do early because it allows us to group case labels before creating
    1464              :    the edges for the CFG, and it speeds up block statement iterators in
    1465              :    all passes later on.
    1466              :    We rerun this pass after CFG is created, to get rid of the labels that
    1467              :    are no longer referenced.  After then we do not run it any more, since
    1468              :    (almost) no new labels should be created.  */
    1469              : 
    1470              : /* A map from basic block index to the leading label of that block.  */
    1471              : struct label_record
    1472              : {
    1473              :   /* The label.  */
    1474              :   tree label;
    1475              : 
    1476              :   /* True if the label is referenced from somewhere.  */
    1477              :   bool used;
    1478              : };
    1479              : 
    1480              : /* Given LABEL return the first label in the same basic block.  */
    1481              : 
    1482              : static tree
    1483     21036168 : main_block_label (tree label, label_record *label_for_bb)
    1484              : {
    1485     21036168 :   basic_block bb = label_to_block (cfun, label);
    1486     21036168 :   tree main_label = label_for_bb[bb->index].label;
    1487              : 
    1488              :   /* label_to_block possibly inserted undefined label into the chain.  */
    1489     21036168 :   if (!main_label)
    1490              :     {
    1491           88 :       label_for_bb[bb->index].label = label;
    1492           88 :       main_label = label;
    1493              :     }
    1494              : 
    1495     21036168 :   label_for_bb[bb->index].used = true;
    1496     21036168 :   return main_label;
    1497              : }
    1498              : 
    1499              : /* Clean up redundant labels within the exception tree.  */
    1500              : 
    1501              : static void
    1502      7570064 : cleanup_dead_labels_eh (label_record *label_for_bb)
    1503              : {
    1504      7570064 :   eh_landing_pad lp;
    1505      7570064 :   eh_region r;
    1506      7570064 :   tree lab;
    1507      7570064 :   int i;
    1508              : 
    1509      7570064 :   if (cfun->eh == NULL)
    1510      7570064 :     return;
    1511              : 
    1512     10962612 :   for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
    1513      3392548 :     if (lp && lp->post_landing_pad)
    1514              :       {
    1515      2110599 :         lab = main_block_label (lp->post_landing_pad, label_for_bb);
    1516      2110599 :         if (lab != lp->post_landing_pad)
    1517              :           {
    1518            0 :             EH_LANDING_PAD_NR (lp->post_landing_pad) = 0;
    1519            0 :             lp->post_landing_pad = lab;
    1520            0 :             EH_LANDING_PAD_NR (lab) = lp->index;
    1521              :           }
    1522              :       }
    1523              : 
    1524     13285294 :   FOR_ALL_EH_REGION (r)
    1525      5715230 :     switch (r->type)
    1526              :       {
    1527              :       case ERT_CLEANUP:
    1528              :       case ERT_MUST_NOT_THROW:
    1529              :         break;
    1530              : 
    1531       136974 :       case ERT_TRY:
    1532       136974 :         {
    1533       136974 :           eh_catch c;
    1534       273223 :           for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
    1535              :             {
    1536       136249 :               lab = c->label;
    1537       136249 :               if (lab)
    1538        90420 :                 c->label = main_block_label (lab, label_for_bb);
    1539              :             }
    1540              :         }
    1541              :         break;
    1542              : 
    1543        12068 :       case ERT_ALLOWED_EXCEPTIONS:
    1544        12068 :         lab = r->u.allowed.label;
    1545        12068 :         if (lab)
    1546         1138 :           r->u.allowed.label = main_block_label (lab, label_for_bb);
    1547              :         break;
    1548              :       }
    1549              : }
    1550              : 
    1551              : 
    1552              : /* Cleanup redundant labels.  This is a three-step process:
    1553              :      1) Find the leading label for each block.
    1554              :      2) Redirect all references to labels to the leading labels.
    1555              :      3) Cleanup all useless labels.  */
    1556              : 
    1557              : void
    1558      7570064 : cleanup_dead_labels (void)
    1559              : {
    1560      7570064 :   basic_block bb;
    1561      7570064 :   label_record *label_for_bb = XCNEWVEC (struct label_record,
    1562              :                                          last_basic_block_for_fn (cfun));
    1563              : 
    1564              :   /* Find a suitable label for each block.  We use the first user-defined
    1565              :      label if there is one, or otherwise just the first label we see.  */
    1566     64882614 :   FOR_EACH_BB_FN (bb, cfun)
    1567              :     {
    1568     57312550 :       gimple_stmt_iterator i;
    1569              : 
    1570    149882394 :       for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
    1571              :         {
    1572     91246723 :           tree label;
    1573     92580353 :           glabel *label_stmt = dyn_cast <glabel *> (gsi_stmt (i));
    1574              : 
    1575     35267803 :           if (!label_stmt)
    1576              :             break;
    1577              : 
    1578     35267803 :           label = gimple_label_label (label_stmt);
    1579              : 
    1580              :           /* If we have not yet seen a label for the current block,
    1581              :              remember this one and see if there are more labels.  */
    1582     35267803 :           if (!label_for_bb[bb->index].label)
    1583              :             {
    1584     32996722 :               label_for_bb[bb->index].label = label;
    1585     32996722 :               continue;
    1586              :             }
    1587              : 
    1588              :           /* If we did see a label for the current block already, but it
    1589              :              is an artificially created label, replace it if the current
    1590              :              label is a user defined label.  */
    1591      2271081 :           if (!DECL_ARTIFICIAL (label)
    1592      2271081 :               && DECL_ARTIFICIAL (label_for_bb[bb->index].label))
    1593              :             {
    1594        10509 :               label_for_bb[bb->index].label = label;
    1595        10509 :               break;
    1596              :             }
    1597              :         }
    1598              :     }
    1599              : 
    1600              :   /* Now redirect all jumps/branches to the selected label.
    1601              :      First do so for each block ending in a control statement.  */
    1602     64882614 :   FOR_EACH_BB_FN (bb, cfun)
    1603              :     {
    1604     57312550 :       gimple *stmt = *gsi_last_bb (bb);
    1605     57312550 :       tree label, new_label;
    1606              : 
    1607     57312550 :       if (!stmt)
    1608       426721 :         continue;
    1609              : 
    1610     56885829 :       switch (gimple_code (stmt))
    1611              :         {
    1612     16857092 :         case GIMPLE_COND:
    1613     16857092 :           {
    1614     16857092 :             gcond *cond_stmt = as_a <gcond *> (stmt);
    1615     16857092 :             label = gimple_cond_true_label (cond_stmt);
    1616     16857092 :             if (label)
    1617              :               {
    1618      5540103 :                 new_label = main_block_label (label, label_for_bb);
    1619      5540103 :                 if (new_label != label)
    1620         9358 :                   gimple_cond_set_true_label (cond_stmt, new_label);
    1621              :               }
    1622              : 
    1623     16857092 :             label = gimple_cond_false_label (cond_stmt);
    1624     16857092 :             if (label)
    1625              :               {
    1626      5540103 :                 new_label = main_block_label (label, label_for_bb);
    1627      5540103 :                 if (new_label != label)
    1628       111098 :                   gimple_cond_set_false_label (cond_stmt, new_label);
    1629              :               }
    1630              :           }
    1631              :           break;
    1632              : 
    1633       114625 :         case GIMPLE_SWITCH:
    1634       114625 :           {
    1635       114625 :             gswitch *switch_stmt = as_a <gswitch *> (stmt);
    1636       114625 :             size_t i, n = gimple_switch_num_labels (switch_stmt);
    1637              : 
    1638              :             /* Replace all destination labels.  */
    1639      1584886 :             for (i = 0; i < n; ++i)
    1640              :               {
    1641      1470261 :                 tree case_label = gimple_switch_label (switch_stmt, i);
    1642      1470261 :                 label = CASE_LABEL (case_label);
    1643      1470261 :                 new_label = main_block_label (label, label_for_bb);
    1644      1470261 :                 if (new_label != label)
    1645       789922 :                   CASE_LABEL (case_label) = new_label;
    1646              :               }
    1647              :             break;
    1648              :           }
    1649              : 
    1650         5634 :         case GIMPLE_ASM:
    1651         5634 :           {
    1652         5634 :             gasm *asm_stmt = as_a <gasm *> (stmt);
    1653         5634 :             int i, n = gimple_asm_nlabels (asm_stmt);
    1654              : 
    1655         8399 :             for (i = 0; i < n; ++i)
    1656              :               {
    1657         2765 :                 tree cons = gimple_asm_label_op (asm_stmt, i);
    1658         2765 :                 tree label = main_block_label (TREE_VALUE (cons), label_for_bb);
    1659         2765 :                 TREE_VALUE (cons) = label;
    1660              :               }
    1661              :             break;
    1662              :           }
    1663              : 
    1664              :         /* We have to handle gotos until they're removed, and we don't
    1665              :            remove them until after we've created the CFG edges.  */
    1666      6280576 :         case GIMPLE_GOTO:
    1667      6280576 :           if (!computed_goto_p (stmt))
    1668              :             {
    1669      6278369 :               ggoto *goto_stmt = as_a <ggoto *> (stmt);
    1670      6278369 :               label = gimple_goto_dest (goto_stmt);
    1671      6278369 :               new_label = main_block_label (label, label_for_bb);
    1672      6278369 :               if (new_label != label)
    1673      1118857 :                 gimple_goto_set_dest (goto_stmt, new_label);
    1674              :             }
    1675              :           break;
    1676              : 
    1677          822 :         case GIMPLE_TRANSACTION:
    1678          822 :           {
    1679          822 :             gtransaction *txn = as_a <gtransaction *> (stmt);
    1680              : 
    1681          822 :             label = gimple_transaction_label_norm (txn);
    1682          822 :             if (label)
    1683              :               {
    1684          802 :                 new_label = main_block_label (label, label_for_bb);
    1685          802 :                 if (new_label != label)
    1686            0 :                   gimple_transaction_set_label_norm (txn, new_label);
    1687              :               }
    1688              : 
    1689          822 :             label = gimple_transaction_label_uninst (txn);
    1690          822 :             if (label)
    1691              :               {
    1692          794 :                 new_label = main_block_label (label, label_for_bb);
    1693          794 :                 if (new_label != label)
    1694            0 :                   gimple_transaction_set_label_uninst (txn, new_label);
    1695              :               }
    1696              : 
    1697          822 :             label = gimple_transaction_label_over (txn);
    1698          822 :             if (label)
    1699              :               {
    1700          814 :                 new_label = main_block_label (label, label_for_bb);
    1701          814 :                 if (new_label != label)
    1702            7 :                   gimple_transaction_set_label_over (txn, new_label);
    1703              :               }
    1704              :           }
    1705              :           break;
    1706              : 
    1707              :         default:
    1708              :           break;
    1709              :       }
    1710              :     }
    1711              : 
    1712              :   /* Do the same for the exception region tree labels.  */
    1713      7570064 :   cleanup_dead_labels_eh (label_for_bb);
    1714              : 
    1715              :   /* Finally, purge dead labels.  All user-defined labels and labels that
    1716              :      can be the target of non-local gotos and labels which have their
    1717              :      address taken are preserved.  */
    1718     64882614 :   FOR_EACH_BB_FN (bb, cfun)
    1719              :     {
    1720     57312550 :       gimple_stmt_iterator i;
    1721     57312550 :       tree label_for_this_bb = label_for_bb[bb->index].label;
    1722              : 
    1723     57312550 :       if (!label_for_this_bb)
    1724     24315740 :         continue;
    1725              : 
    1726              :       /* If the main label of the block is unused, we may still remove it.  */
    1727     32996810 :       if (!label_for_bb[bb->index].used)
    1728     15413902 :         label_for_this_bb = NULL;
    1729              : 
    1730    101261523 :       for (i = gsi_start_bb (bb); !gsi_end_p (i); )
    1731              :         {
    1732     67367768 :           tree label;
    1733     68264713 :           glabel *label_stmt = dyn_cast <glabel *> (gsi_stmt (i));
    1734              : 
    1735     35267903 :           if (!label_stmt)
    1736              :             break;
    1737              : 
    1738     35267903 :           label = gimple_label_label (label_stmt);
    1739              : 
    1740     35267903 :           if (label == label_for_this_bb
    1741     17684995 :               || !DECL_ARTIFICIAL (label)
    1742     16952022 :               || DECL_NONLOCAL (label)
    1743     52218463 :               || FORCED_LABEL (label))
    1744     18344107 :             gsi_next (&i);
    1745              :           else
    1746              :             {
    1747     16923796 :               gcc_checking_assert (EH_LANDING_PAD_NR (label) == 0);
    1748     16923796 :               gsi_remove (&i, true);
    1749              :             }
    1750              :         }
    1751              :     }
    1752              : 
    1753      7570064 :   free (label_for_bb);
    1754      7570064 : }
    1755              : 
    1756              : /* Scan the sorted vector of cases in STMT (a GIMPLE_SWITCH) and combine
    1757              :    the ones jumping to the same label.
    1758              :    Eg. three separate entries 1: 2: 3: become one entry 1..3:  */
    1759              : 
    1760              : bool
    1761       279744 : group_case_labels_stmt (gswitch *stmt)
    1762              : {
    1763       279744 :   int old_size = gimple_switch_num_labels (stmt);
    1764       279744 :   int i, next_index, new_size;
    1765       279744 :   basic_block default_bb = NULL;
    1766              : 
    1767       279744 :   default_bb = gimple_switch_default_bb (cfun, stmt);
    1768              : 
    1769              :   /* Look for possible opportunities to merge cases.  */
    1770       279744 :   new_size = i = 1;
    1771      2260679 :   while (i < old_size)
    1772              :     {
    1773      1701191 :       tree base_case, base_high;
    1774      1701191 :       basic_block base_bb;
    1775              : 
    1776      1701191 :       base_case = gimple_switch_label (stmt, i);
    1777              : 
    1778      1701191 :       gcc_assert (base_case);
    1779      1701191 :       base_bb = label_to_block (cfun, CASE_LABEL (base_case));
    1780              : 
    1781              :       /* Discard cases that have the same destination as the default case.  */
    1782      1709032 :       if (base_bb == NULL
    1783      1701191 :           || base_bb == default_bb)
    1784              :         {
    1785         7841 :           i++;
    1786         7841 :           continue;
    1787              :         }
    1788              : 
    1789      3386700 :       base_high = CASE_HIGH (base_case)
    1790      1693350 :           ? CASE_HIGH (base_case)
    1791      1615434 :           : CASE_LOW (base_case);
    1792      1693350 :       next_index = i + 1;
    1793              : 
    1794              :       /* Try to merge case labels.  Break out when we reach the end
    1795              :          of the label vector or when we cannot merge the next case
    1796              :          label with the current one.  */
    1797      2440049 :       while (next_index < old_size)
    1798              :         {
    1799      2162230 :           tree merge_case = gimple_switch_label (stmt, next_index);
    1800      2162230 :           basic_block merge_bb = label_to_block (cfun, CASE_LABEL (merge_case));
    1801      2162230 :           wide_int bhp1 = wi::to_wide (base_high) + 1;
    1802              : 
    1803              :           /* Merge the cases if they jump to the same place,
    1804              :              and their ranges are consecutive.  */
    1805      2162230 :           if (merge_bb == base_bb
    1806      3007550 :               && wi::to_wide (CASE_LOW (merge_case)) == bhp1)
    1807              :             {
    1808       746699 :               base_high
    1809      1493398 :                 = (CASE_HIGH (merge_case)
    1810       746699 :                    ? CASE_HIGH (merge_case) : CASE_LOW (merge_case));
    1811       746699 :               CASE_HIGH (base_case) = base_high;
    1812       746699 :               next_index++;
    1813              :             }
    1814              :           else
    1815              :             break;
    1816      2162230 :         }
    1817              : 
    1818      1693350 :       if (new_size < i)
    1819        72066 :         gimple_switch_set_label (stmt, new_size,
    1820              :                                  gimple_switch_label (stmt, i));
    1821      1693350 :       i = next_index;
    1822      1693350 :       new_size++;
    1823              :     }
    1824              : 
    1825       279744 :   gcc_assert (new_size <= old_size);
    1826              : 
    1827       279744 :   if (new_size < old_size)
    1828        19603 :     gimple_switch_set_num_labels (stmt, new_size);
    1829              : 
    1830       279744 :   return new_size < old_size;
    1831              : }
    1832              : 
    1833              : /* Look for blocks ending in a multiway branch (a GIMPLE_SWITCH),
    1834              :    and scan the sorted vector of cases.  Combine the ones jumping to the
    1835              :    same label.  */
    1836              : 
    1837              : bool
    1838      4542977 : group_case_labels (void)
    1839              : {
    1840      4542977 :   basic_block bb;
    1841      4542977 :   bool changed = false;
    1842              : 
    1843     39579777 :   FOR_EACH_BB_FN (bb, cfun)
    1844              :     {
    1845    104891647 :       if (gswitch *stmt = safe_dyn_cast <gswitch *> (*gsi_last_bb (bb)))
    1846        60851 :         changed |= group_case_labels_stmt (stmt);
    1847              :     }
    1848              : 
    1849      4542977 :   return changed;
    1850              : }
    1851              : 
    1852              : /* Checks whether we can merge block B into block A.  */
    1853              : 
    1854              : static bool
    1855    431517578 : gimple_can_merge_blocks_p (basic_block a, basic_block b)
    1856              : {
    1857    431517578 :   gimple *stmt;
    1858              : 
    1859    431517578 :   if (!single_succ_p (a))
    1860              :     return false;
    1861              : 
    1862    205143648 :   if (single_succ_edge (a)->flags & EDGE_COMPLEX)
    1863              :     return false;
    1864              : 
    1865    192940782 :   if (single_succ (a) != b)
    1866              :     return false;
    1867              : 
    1868    192940782 :   if (!single_pred_p (b))
    1869              :     return false;
    1870              : 
    1871     94575149 :   if (a == ENTRY_BLOCK_PTR_FOR_FN (cfun)
    1872     61776049 :       || b == EXIT_BLOCK_PTR_FOR_FN (cfun))
    1873              :     return false;
    1874              : 
    1875              :   /* If A ends by a statement causing exceptions or something similar, we
    1876              :      cannot merge the blocks.  */
    1877     34540413 :   stmt = *gsi_last_bb (a);
    1878     34540413 :   if (stmt && stmt_ends_bb_p (stmt))
    1879              :     return false;
    1880              : 
    1881              :   /* Check if the compiler-inserted nop should block merges.  */
    1882     29013986 :   if (stmt && gimple_nop_p (stmt)
    1883         4945 :       && gimple_location (stmt) == DECL_SOURCE_LOCATION (cfun->decl)
    1884     32667790 :       && coverage_suppressed_p (a) && !coverage_suppressed_p (b))
    1885              :     return false;
    1886              : 
    1887              :   /* We cannot merge blocks if one has suppressed coverage and the other hasn't.
    1888              :      The exception is when the merge-into block is empty AND is the one with
    1889              :      coverage suppressed.  This can happen for code like this:
    1890              : 
    1891              :      while (cond)
    1892              :        #pragma GCC suppress_coverage begin
    1893              :        foo ();
    1894              :        #pragma GCC suppress_coverage end
    1895              :   */
    1896     32667758 :   if (coverage_suppressed_p (a) != coverage_suppressed_p (b)
    1897     32667758 :       && !(coverage_suppressed_p (a) && gimple_empty_block_p (a)))
    1898              :       return false;
    1899              : 
    1900              :   /* Examine the labels at the beginning of B.  */
    1901     65526507 :   for (gimple_stmt_iterator gsi = gsi_start_bb (b); !gsi_end_p (gsi);
    1902       197753 :        gsi_next (&gsi))
    1903              :     {
    1904     29229325 :       tree lab;
    1905     29229325 :       glabel *label_stmt = dyn_cast <glabel *> (gsi_stmt (gsi));
    1906      1886499 :       if (!label_stmt)
    1907              :         break;
    1908      1886499 :       lab = gimple_label_label (label_stmt);
    1909              : 
    1910              :       /* Do not remove user forced labels or for -O0 any user labels.  */
    1911      1944408 :       if (!DECL_ARTIFICIAL (lab) && (!optimize || FORCED_LABEL (lab)))
    1912    431517578 :         return false;
    1913              :     }
    1914              : 
    1915              :   /* Protect simple loop latches.  We only want to avoid merging
    1916              :      the latch with the loop header or with a block in another
    1917              :      loop in this case.  */
    1918     30975631 :   if (current_loops
    1919     28141400 :       && b->loop_father->latch == b
    1920       434958 :       && loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES)
    1921     31013040 :       && (b->loop_father->header == a
    1922        25508 :           || b->loop_father != a->loop_father))
    1923              :     return false;
    1924              : 
    1925              :   /* It must be possible to eliminate all phi nodes in B.  If ssa form
    1926              :      is not up-to-date and a name-mapping is registered, we cannot eliminate
    1927              :      any phis.  Symbols marked for renaming are never a problem though.  */
    1928     36936014 :   for (gphi_iterator gsi = gsi_start_phis (b); !gsi_end_p (gsi);
    1929      5972401 :        gsi_next (&gsi))
    1930              :     {
    1931      5972401 :       gphi *phi = gsi.phi ();
    1932              :       /* Technically only new names matter.  */
    1933      5972401 :       if (name_registered_for_update_p (PHI_RESULT (phi)))
    1934            0 :         return false;
    1935              :     }
    1936              : 
    1937              :   /* When not optimizing, don't merge if we'd lose goto_locus.  */
    1938     30963613 :   if (!optimize
    1939     30963613 :       && single_succ_edge (a)->goto_locus != UNKNOWN_LOCATION)
    1940              :     {
    1941       589128 :       location_t goto_locus = single_succ_edge (a)->goto_locus;
    1942       589128 :       gimple_stmt_iterator prev, next;
    1943       589128 :       prev = gsi_last_nondebug_bb (a);
    1944       589128 :       next = gsi_after_labels (b);
    1945       589128 :       if (!gsi_end_p (next) && is_gimple_debug (gsi_stmt (next)))
    1946            6 :         gsi_next_nondebug (&next);
    1947       589128 :       if ((gsi_end_p (prev)
    1948       442981 :            || gimple_location (gsi_stmt (prev)) != goto_locus)
    1949       989139 :           && (gsi_end_p (next)
    1950       497602 :               || gimple_location (gsi_stmt (next)) != goto_locus))
    1951       545966 :         return false;
    1952              :     }
    1953              : 
    1954              :   return true;
    1955              : }
    1956              : 
    1957              : /* Replaces all uses of NAME by VAL.  */
    1958              : 
    1959              : void
    1960      4030675 : replace_uses_by (tree name, tree val)
    1961              : {
    1962      4030675 :   imm_use_iterator imm_iter;
    1963      4030675 :   use_operand_p use;
    1964      4030675 :   gimple *stmt;
    1965      4030675 :   edge e;
    1966      4030675 :   auto_bitmap eh_cleanup_bbs;
    1967              : 
    1968     11366718 :   FOR_EACH_IMM_USE_STMT (stmt, imm_iter, name)
    1969              :     {
    1970              :       /* Mark the block if we change the last stmt in it.  */
    1971      7336043 :       if (cfgcleanup_altered_bbs
    1972      7336043 :           && stmt_ends_bb_p (stmt))
    1973       797749 :         bitmap_set_bit (cfgcleanup_altered_bbs, gimple_bb (stmt)->index);
    1974              : 
    1975     14989116 :       FOR_EACH_IMM_USE_ON_STMT (use, imm_iter)
    1976              :         {
    1977      7494558 :           replace_exp (use, val);
    1978              : 
    1979      7494558 :           if (gimple_code (stmt) == GIMPLE_PHI)
    1980              :             {
    1981      2499663 :               e = gimple_phi_arg_edge (as_a <gphi *> (stmt),
    1982      2499663 :                                        PHI_ARG_INDEX_FROM_USE (use));
    1983      2499663 :               if (e->flags & EDGE_ABNORMAL
    1984      2499663 :                   && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val))
    1985              :                 {
    1986              :                   /* This can only occur for virtual operands, since
    1987              :                      for the real ones SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
    1988              :                      would prevent replacement.  */
    1989            0 :                   gcc_checking_assert (virtual_operand_p (name));
    1990            0 :                   SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val) = 1;
    1991              :                 }
    1992              :             }
    1993              :         }
    1994              : 
    1995      7336043 :       if (gimple_code (stmt) != GIMPLE_PHI)
    1996              :         {
    1997      4986757 :           gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
    1998      4986757 :           gimple *orig_stmt = stmt;
    1999      4986757 :           size_t i;
    2000              : 
    2001              :           /* FIXME.  It shouldn't be required to keep TREE_CONSTANT
    2002              :              on ADDR_EXPRs up-to-date on GIMPLE.  Propagation will
    2003              :              only change sth from non-invariant to invariant, and only
    2004              :              when propagating constants.  */
    2005      4986757 :           if (is_gimple_min_invariant (val))
    2006      1750734 :             for (i = 0; i < gimple_num_ops (stmt); i++)
    2007              :               {
    2008      1266884 :                 tree op = gimple_op (stmt, i);
    2009              :                 /* Operands may be empty here.  For example, the labels
    2010              :                    of a GIMPLE_COND are nulled out following the creation
    2011              :                    of the corresponding CFG edges.  */
    2012      1266884 :                 if (op && TREE_CODE (op) == ADDR_EXPR)
    2013        65268 :                   recompute_tree_invariant_for_addr_expr (op);
    2014              :               }
    2015      4986757 :           update_stmt (stmt);
    2016              : 
    2017      4986757 :           if (fold_stmt (&gsi))
    2018              :             {
    2019       517327 :               stmt = gsi_stmt (gsi);
    2020       517327 :               update_stmt (stmt);
    2021              :             }
    2022              : 
    2023      4986757 :           if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
    2024         1025 :             bitmap_set_bit (eh_cleanup_bbs, gimple_bb (stmt)->index);
    2025              :         }
    2026      4030675 :     }
    2027              : 
    2028      4030675 :   if (!bitmap_empty_p (eh_cleanup_bbs))
    2029          986 :     gimple_purge_all_dead_eh_edges (eh_cleanup_bbs);
    2030              : 
    2031      4030675 :   gcc_checking_assert (has_zero_uses (name));
    2032              : 
    2033              :   /* Also update the trees stored in loop structures.  */
    2034      4030675 :   if (current_loops)
    2035              :     {
    2036    140268027 :       for (auto loop : loops_list (cfun, 0))
    2037    132206677 :           substitute_in_loop_info (loop, name, val);
    2038              :     }
    2039      4030675 : }
    2040              : 
    2041              : /* Merge block B into block A.  */
    2042              : 
    2043              : static void
    2044     17951114 : gimple_merge_blocks (basic_block a, basic_block b)
    2045              : {
    2046     17951114 :   gimple_stmt_iterator last, gsi;
    2047     17951114 :   gphi_iterator psi;
    2048              : 
    2049     17951285 :   if (coverage_suppressed_p (a) && !coverage_suppressed_p (b)
    2050     17951137 :       && gimple_empty_block_p (a))
    2051           23 :     suppress_coverage_unset (a);
    2052              : 
    2053     17951114 :   if (dump_file)
    2054        19976 :     fprintf (dump_file, "Merging blocks %d and %d\n", a->index, b->index);
    2055              : 
    2056              :   /* Remove all single-valued PHI nodes from block B of the form
    2057              :      V_i = PHI <V_j> by propagating V_j to all the uses of V_i.  */
    2058     17951114 :   gsi = gsi_last_bb (a);
    2059     21939613 :   for (psi = gsi_start_phis (b); !gsi_end_p (psi); )
    2060              :     {
    2061      3988499 :       gimple *phi = gsi_stmt (psi);
    2062      3988499 :       tree def = gimple_phi_result (phi), use = gimple_phi_arg_def (phi, 0);
    2063      3988499 :       gimple *copy;
    2064      3988499 :       bool may_replace_uses = (virtual_operand_p (def)
    2065      3988499 :                                || may_propagate_copy (def, use));
    2066              : 
    2067              :       /* In case we maintain loop closed ssa form, do not propagate arguments
    2068              :          of loop exit phi nodes.  */
    2069      3988499 :       if (current_loops
    2070      3988499 :           && loops_state_satisfies_p (LOOP_CLOSED_SSA)
    2071       632847 :           && !virtual_operand_p (def)
    2072       463557 :           && TREE_CODE (use) == SSA_NAME
    2073      4336236 :           && a->loop_father != b->loop_father)
    2074              :         may_replace_uses = false;
    2075              : 
    2076      3988268 :       if (!may_replace_uses)
    2077              :         {
    2078         1100 :           gcc_assert (!virtual_operand_p (def));
    2079              : 
    2080              :           /* Note that just emitting the copies is fine -- there is no problem
    2081              :              with ordering of phi nodes.  This is because A is the single
    2082              :              predecessor of B, therefore results of the phi nodes cannot
    2083              :              appear as arguments of the phi nodes.  */
    2084          550 :           copy = gimple_build_assign (def, use);
    2085          550 :           gsi_insert_after (&gsi, copy, GSI_NEW_STMT);
    2086          550 :           remove_phi_node (&psi, false);
    2087              :         }
    2088              :       else
    2089              :         {
    2090              :           /* If we deal with a PHI for virtual operands, we can simply
    2091              :              propagate these without fussing with folding or updating
    2092              :              the stmt.  */
    2093      7975898 :           if (virtual_operand_p (def))
    2094              :             {
    2095      1534065 :               imm_use_iterator iter;
    2096      1534065 :               use_operand_p use_p;
    2097      1534065 :               gimple *stmt;
    2098              : 
    2099      4421312 :               FOR_EACH_IMM_USE_STMT (stmt, iter, def)
    2100      5806482 :                 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
    2101      2903241 :                   SET_USE (use_p, use);
    2102              : 
    2103      1534065 :               if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def))
    2104          281 :                 SSA_NAME_OCCURS_IN_ABNORMAL_PHI (use) = 1;
    2105              :             }
    2106              :           else
    2107      2453884 :             replace_uses_by (def, use);
    2108              : 
    2109      3987949 :           remove_phi_node (&psi, true);
    2110              :         }
    2111              :     }
    2112              : 
    2113              :   /* Ensure that B follows A.  */
    2114     17951114 :   move_block_after (b, a);
    2115              : 
    2116     17951114 :   gcc_assert (single_succ_edge (a)->flags & EDGE_FALLTHRU);
    2117     35902228 :   gcc_assert (!*gsi_last_bb (a)
    2118              :               || !stmt_ends_bb_p (*gsi_last_bb (a)));
    2119              : 
    2120              :   /* Remove labels from B and set gimple_bb to A for other statements.  */
    2121    140350499 :   for (gsi = gsi_start_bb (b); !gsi_end_p (gsi);)
    2122              :     {
    2123    104448271 :       gimple *stmt = gsi_stmt (gsi);
    2124    104448271 :       if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
    2125              :         {
    2126       116107 :           tree label = gimple_label_label (label_stmt);
    2127       116107 :           int lp_nr;
    2128              : 
    2129       116107 :           gsi_remove (&gsi, false);
    2130              : 
    2131              :           /* Now that we can thread computed gotos, we might have
    2132              :              a situation where we have a forced label in block B
    2133              :              However, the label at the start of block B might still be
    2134              :              used in other ways (think about the runtime checking for
    2135              :              Fortran assigned gotos).  So we cannot just delete the
    2136              :              label.  Instead we move the label to the start of block A.  */
    2137       116107 :           if (FORCED_LABEL (label))
    2138              :             {
    2139         5282 :               gimple_stmt_iterator dest_gsi = gsi_start_bb (a);
    2140         5282 :               tree first_label = NULL_TREE;
    2141         5282 :               if (!gsi_end_p (dest_gsi))
    2142         5260 :                 if (glabel *first_label_stmt
    2143         5260 :                     = dyn_cast <glabel *> (gsi_stmt (dest_gsi)))
    2144         4489 :                   first_label = gimple_label_label (first_label_stmt);
    2145         4489 :               if (first_label
    2146         4489 :                   && (DECL_NONLOCAL (first_label)
    2147         4489 :                       || EH_LANDING_PAD_NR (first_label) != 0))
    2148           12 :                 gsi_insert_after (&dest_gsi, stmt, GSI_NEW_STMT);
    2149              :               else
    2150         5270 :                 gsi_insert_before (&dest_gsi, stmt, GSI_NEW_STMT);
    2151              :             }
    2152              :           /* Other user labels keep around in a form of a debug stmt.  */
    2153       110825 :           else if (!DECL_ARTIFICIAL (label) && MAY_HAVE_DEBUG_BIND_STMTS)
    2154              :             {
    2155         9074 :               gimple *dbg = gimple_build_debug_bind (label,
    2156              :                                                      integer_zero_node,
    2157              :                                                      stmt);
    2158         9074 :               gimple_debug_bind_reset_value (dbg);
    2159         9074 :               gsi_insert_before (&gsi, dbg, GSI_SAME_STMT);
    2160              :             }
    2161              : 
    2162       116107 :           lp_nr = EH_LANDING_PAD_NR (label);
    2163       116107 :           if (lp_nr)
    2164              :             {
    2165         8894 :               eh_landing_pad lp = get_eh_landing_pad_from_number (lp_nr);
    2166         8894 :               lp->post_landing_pad = NULL;
    2167              :             }
    2168              :         }
    2169              :       else
    2170              :         {
    2171    104332164 :           gimple_set_bb (stmt, a);
    2172    104332164 :           gsi_next (&gsi);
    2173              :         }
    2174              :     }
    2175              : 
    2176              :   /* When merging two BBs, if their counts are different, the larger count
    2177              :      is selected as the new bb count. This is to handle inconsistent
    2178              :      profiles.  */
    2179     17951114 :   if (a->loop_father == b->loop_father)
    2180              :     {
    2181     17861240 :       a->count = a->count.merge (b->count);
    2182              :     }
    2183              : 
    2184              :   /* Merge the sequences.  */
    2185     17951114 :   last = gsi_last_bb (a);
    2186     35902228 :   gsi_insert_seq_after (&last, bb_seq (b), GSI_NEW_STMT);
    2187     17951114 :   set_bb_seq (b, NULL);
    2188              : 
    2189     17951114 :   if (cfgcleanup_altered_bbs)
    2190     17921947 :     bitmap_set_bit (cfgcleanup_altered_bbs, a->index);
    2191     17951114 : }
    2192              : 
    2193              : 
    2194              : /* Return the one of two successors of BB that is not reachable by a
    2195              :    complex edge, if there is one.  Else, return BB.  We use
    2196              :    this in optimizations that use post-dominators for their heuristics,
    2197              :    to catch the cases in C++ where function calls are involved.  */
    2198              : 
    2199              : basic_block
    2200            6 : single_noncomplex_succ (basic_block bb)
    2201              : {
    2202            6 :   edge e0, e1;
    2203            6 :   if (EDGE_COUNT (bb->succs) != 2)
    2204              :     return bb;
    2205              : 
    2206            6 :   e0 = EDGE_SUCC (bb, 0);
    2207            6 :   e1 = EDGE_SUCC (bb, 1);
    2208            6 :   if (e0->flags & EDGE_COMPLEX)
    2209            6 :     return e1->dest;
    2210            0 :   if (e1->flags & EDGE_COMPLEX)
    2211            0 :     return e0->dest;
    2212              : 
    2213              :   return bb;
    2214              : }
    2215              : 
    2216              : /* T is CALL_EXPR.  Set current_function_calls_* flags.  */
    2217              : 
    2218              : void
    2219     55058368 : notice_special_calls (gcall *call)
    2220              : {
    2221     55058368 :   int flags = gimple_call_flags (call);
    2222              : 
    2223     55058368 :   if (flags & ECF_MAY_BE_ALLOCA)
    2224       160451 :     cfun->calls_alloca = true;
    2225     55058368 :   if (flags & ECF_RETURNS_TWICE)
    2226         8003 :     cfun->calls_setjmp = true;
    2227     55058368 :   if (gimple_call_must_tail_p (call))
    2228         3634 :     cfun->has_musttail = true;
    2229     55058368 : }
    2230              : 
    2231              : 
    2232              : /* Clear flags set by notice_special_calls.  Used by dead code removal
    2233              :    to update the flags.  */
    2234              : 
    2235              : void
    2236      8300568 : clear_special_calls (void)
    2237              : {
    2238      8300568 :   cfun->calls_alloca = false;
    2239      8300568 :   cfun->calls_setjmp = false;
    2240      8300568 :   cfun->has_musttail = false;
    2241      8300568 : }
    2242              : 
    2243              : /* Remove PHI nodes associated with basic block BB and all edges out of BB.  */
    2244              : 
    2245              : static void
    2246     36664810 : remove_phi_nodes_and_edges_for_unreachable_block (basic_block bb)
    2247              : {
    2248              :   /* Since this block is no longer reachable, we can just delete all
    2249              :      of its PHI nodes.  */
    2250     36664810 :   remove_phi_nodes (bb);
    2251              : 
    2252              :   /* Remove edges to BB's successors.  */
    2253    107901000 :   while (EDGE_COUNT (bb->succs) > 0)
    2254     34571380 :     remove_edge (EDGE_SUCC (bb, 0));
    2255     36664810 : }
    2256              : 
    2257              : 
    2258              : /* Remove statements of basic block BB.  */
    2259              : 
    2260              : static void
    2261     36664810 : remove_bb (basic_block bb)
    2262              : {
    2263     36664810 :   gimple_stmt_iterator i;
    2264              : 
    2265     36664810 :   if (dump_file)
    2266              :     {
    2267        47458 :       fprintf (dump_file, "Removing basic block %d\n", bb->index);
    2268        47458 :       if (dump_flags & TDF_DETAILS)
    2269              :         {
    2270        33177 :           dump_bb (dump_file, bb, 0, TDF_BLOCKS);
    2271        33177 :           fprintf (dump_file, "\n");
    2272              :         }
    2273              :     }
    2274              : 
    2275     36664810 :   if (current_loops)
    2276              :     {
    2277     34705270 :       class loop *loop = bb->loop_father;
    2278              : 
    2279              :       /* If a loop gets removed, clean up the information associated
    2280              :          with it.  */
    2281     34705270 :       if (loop->latch == bb
    2282     34501954 :           || loop->header == bb)
    2283       250312 :         free_numbers_of_iterations_estimates (loop);
    2284              :     }
    2285              : 
    2286              :   /* Remove all the instructions in the block.  */
    2287     36664810 :   if (bb_seq (bb) != NULL)
    2288              :     {
    2289              :       /* Walk backwards so as to get a chance to substitute all
    2290              :          released DEFs into debug stmts.  See
    2291              :          eliminate_unnecessary_stmts() in tree-ssa-dce.cc for more
    2292              :          details.  */
    2293     29903132 :       for (i = gsi_last_bb (bb); !gsi_end_p (i);)
    2294              :         {
    2295     22758052 :           gimple *stmt = gsi_stmt (i);
    2296     22758052 :           glabel *label_stmt = dyn_cast <glabel *> (stmt);
    2297      2011267 :           if (label_stmt
    2298      2011267 :               && (FORCED_LABEL (gimple_label_label (label_stmt))
    2299      2008288 :                   || DECL_NONLOCAL (gimple_label_label (label_stmt))))
    2300              :             {
    2301         2981 :               basic_block new_bb;
    2302         2981 :               gimple_stmt_iterator new_gsi;
    2303              : 
    2304              :               /* A non-reachable non-local label may still be referenced.
    2305              :                  But it no longer needs to carry the extra semantics of
    2306              :                  non-locality.  */
    2307         2981 :               if (DECL_NONLOCAL (gimple_label_label (label_stmt)))
    2308              :                 {
    2309            2 :                   DECL_NONLOCAL (gimple_label_label (label_stmt)) = 0;
    2310            2 :                   FORCED_LABEL (gimple_label_label (label_stmt)) = 1;
    2311              :                 }
    2312              : 
    2313         2981 :               new_bb = bb->prev_bb;
    2314              :               /* Don't move any labels into ENTRY block.  */
    2315         2981 :               if (new_bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
    2316              :                 {
    2317            0 :                   new_bb = single_succ (new_bb);
    2318            0 :                   gcc_assert (new_bb != bb);
    2319              :                 }
    2320         2981 :               if ((unsigned) bb->index < bb_to_omp_idx.length ()
    2321            8 :                   && ((unsigned) new_bb->index >= bb_to_omp_idx.length ()
    2322            8 :                       || (bb_to_omp_idx[bb->index]
    2323            8 :                           != bb_to_omp_idx[new_bb->index])))
    2324              :                 {
    2325              :                   /* During cfg pass make sure to put orphaned labels
    2326              :                      into the right OMP region.  */
    2327              :                   unsigned int i;
    2328              :                   int idx;
    2329           24 :                   new_bb = NULL;
    2330           24 :                   FOR_EACH_VEC_ELT (bb_to_omp_idx, i, idx)
    2331           24 :                     if (i >= NUM_FIXED_BLOCKS
    2332            8 :                         && idx == bb_to_omp_idx[bb->index]
    2333           32 :                         && i != (unsigned) bb->index)
    2334              :                       {
    2335            8 :                         new_bb = BASIC_BLOCK_FOR_FN (cfun, i);
    2336            8 :                         break;
    2337              :                       }
    2338            8 :                   if (new_bb == NULL)
    2339              :                     {
    2340            0 :                       new_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
    2341            0 :                       gcc_assert (new_bb != bb);
    2342              :                     }
    2343              :                 }
    2344         2981 :               new_gsi = gsi_after_labels (new_bb);
    2345         2981 :               gsi_remove (&i, false);
    2346         2981 :               gsi_insert_before (&new_gsi, stmt, GSI_NEW_STMT);
    2347              :             }
    2348              :           else
    2349              :             {
    2350              :               /* Release SSA definitions.  */
    2351     22755071 :               release_defs (stmt);
    2352     22755071 :               gsi_remove (&i, true);
    2353              :             }
    2354              : 
    2355     22758052 :           if (gsi_end_p (i))
    2356     45516104 :             i = gsi_last_bb (bb);
    2357              :           else
    2358            0 :             gsi_prev (&i);
    2359              :         }
    2360              :     }
    2361              : 
    2362     36664810 :   if ((unsigned) bb->index < bb_to_omp_idx.length ())
    2363        13668 :     bb_to_omp_idx[bb->index] = -1;
    2364     36664810 :   remove_phi_nodes_and_edges_for_unreachable_block (bb);
    2365     36664810 :   bb->il.gimple.seq = NULL;
    2366     36664810 :   bb->il.gimple.phi_nodes = NULL;
    2367     36664810 : }
    2368              : 
    2369              : 
    2370              : /* Given a basic block BB and a value VAL for use in the final statement
    2371              :    of the block (if a GIMPLE_COND, GIMPLE_SWITCH, or computed goto), return
    2372              :    the edge that will be taken out of the block.
    2373              :    If VAL is NULL_TREE, then the current value of the final statement's
    2374              :    predicate or index is used.
    2375              :    If the value does not match a unique edge, NULL is returned.  */
    2376              : 
    2377              : edge
    2378    253641655 : find_taken_edge (basic_block bb, tree val)
    2379              : {
    2380    253641655 :   gimple *stmt;
    2381              : 
    2382    253641655 :   stmt = *gsi_last_bb (bb);
    2383              : 
    2384              :   /* Handle ENTRY and EXIT.  */
    2385    253641655 :   if (!stmt)
    2386              :     ;
    2387              : 
    2388    249991702 :   else if (gimple_code (stmt) == GIMPLE_COND)
    2389    203169159 :     return find_taken_edge_cond_expr (as_a <gcond *> (stmt), val);
    2390              : 
    2391     46822543 :   else if (gimple_code (stmt) == GIMPLE_SWITCH)
    2392      1069712 :     return find_taken_edge_switch_expr (as_a <gswitch *> (stmt), val);
    2393              : 
    2394     45752831 :   else if (computed_goto_p (stmt))
    2395              :     {
    2396              :       /* Only optimize if the argument is a label, if the argument is
    2397              :          not a label then we cannot construct a proper CFG.
    2398              : 
    2399              :          It may be the case that we only need to allow the LABEL_REF to
    2400              :          appear inside an ADDR_EXPR, but we also allow the LABEL_REF to
    2401              :          appear inside a LABEL_EXPR just to be safe.  */
    2402         3001 :       if (val
    2403         1698 :           && (TREE_CODE (val) == ADDR_EXPR || TREE_CODE (val) == LABEL_EXPR)
    2404         3410 :           && TREE_CODE (TREE_OPERAND (val, 0)) == LABEL_DECL)
    2405          320 :         return find_taken_edge_computed_goto (bb, TREE_OPERAND (val, 0));
    2406              :     }
    2407              : 
    2408              :   /* Otherwise we only know the taken successor edge if it's unique.  */
    2409     49402464 :   return single_succ_p (bb) ? single_succ_edge (bb) : NULL;
    2410              : }
    2411              : 
    2412              : /* Given a constant value VAL and the entry block BB to a GOTO_EXPR
    2413              :    statement, determine which of the outgoing edges will be taken out of the
    2414              :    block.  Return NULL if either edge may be taken.  */
    2415              : 
    2416              : static edge
    2417          320 : find_taken_edge_computed_goto (basic_block bb, tree val)
    2418              : {
    2419          320 :   basic_block dest;
    2420          320 :   edge e = NULL;
    2421              : 
    2422          320 :   dest = label_to_block (cfun, val);
    2423          320 :   if (dest)
    2424          316 :     e = find_edge (bb, dest);
    2425              : 
    2426              :   /* It's possible for find_edge to return NULL here on invalid code
    2427              :      that abuses the labels-as-values extension (e.g. code that attempts to
    2428              :      jump *between* functions via stored labels-as-values; PR 84136).
    2429              :      If so, then we simply return that NULL for the edge.
    2430              :      We don't currently have a way of detecting such invalid code, so we
    2431              :      can't assert that it was the case when a NULL edge occurs here.  */
    2432              : 
    2433          320 :   return e;
    2434              : }
    2435              : 
    2436              : /* Given COND_STMT and a constant value VAL for use as the predicate,
    2437              :    determine which of the two edges will be taken out of
    2438              :    the statement's block.  Return NULL if either edge may be taken.
    2439              :    If VAL is NULL_TREE, then the current value of COND_STMT's predicate
    2440              :    is used.  */
    2441              : 
    2442              : static edge
    2443    203169159 : find_taken_edge_cond_expr (const gcond *cond_stmt, tree val)
    2444              : {
    2445    203169159 :   edge true_edge, false_edge;
    2446              : 
    2447    203169159 :   if (val == NULL_TREE)
    2448              :     {
    2449              :       /* Use the current value of the predicate.  */
    2450    188794825 :       if (gimple_cond_true_p (cond_stmt))
    2451        72175 :         val = integer_one_node;
    2452    188722650 :       else if (gimple_cond_false_p (cond_stmt))
    2453       162845 :         val = integer_zero_node;
    2454              :       else
    2455              :         return NULL;
    2456              :     }
    2457     14374334 :   else if (TREE_CODE (val) != INTEGER_CST)
    2458              :     return NULL;
    2459              : 
    2460     13338460 :   extract_true_false_edges_from_block (gimple_bb (cond_stmt),
    2461              :                                        &true_edge, &false_edge);
    2462              : 
    2463     13338460 :   return (integer_zerop (val) ? false_edge : true_edge);
    2464              : }
    2465              : 
    2466              : /* Given SWITCH_STMT and an INTEGER_CST VAL for use as the index, determine
    2467              :    which edge will be taken out of the statement's block.  Return NULL if any
    2468              :    edge may be taken.
    2469              :    If VAL is NULL_TREE, then the current value of SWITCH_STMT's index
    2470              :    is used.  */
    2471              : 
    2472              : edge
    2473      1069862 : find_taken_edge_switch_expr (const gswitch *switch_stmt, tree val)
    2474              : {
    2475      1069862 :   basic_block dest_bb;
    2476      1069862 :   edge e;
    2477      1069862 :   tree taken_case;
    2478              : 
    2479      1069862 :   if (gimple_switch_num_labels (switch_stmt) == 1)
    2480            0 :     taken_case = gimple_switch_default_label (switch_stmt);
    2481              :   else
    2482              :     {
    2483      1069862 :       if (val == NULL_TREE)
    2484       151145 :         val = gimple_switch_index (switch_stmt);
    2485      1069862 :       if (TREE_CODE (val) != INTEGER_CST)
    2486              :         return NULL;
    2487              :       else
    2488        23238 :         taken_case = find_case_label_for_value (switch_stmt, val);
    2489              :     }
    2490        23238 :   dest_bb = label_to_block (cfun, CASE_LABEL (taken_case));
    2491              : 
    2492        23238 :   e = find_edge (gimple_bb (switch_stmt), dest_bb);
    2493        23238 :   gcc_assert (e);
    2494              :   return e;
    2495              : }
    2496              : 
    2497              : 
    2498              : /* Return the CASE_LABEL_EXPR that SWITCH_STMT will take for VAL.
    2499              :    We can make optimal use here of the fact that the case labels are
    2500              :    sorted: We can do a binary search for a case matching VAL.  */
    2501              : 
    2502              : tree
    2503        23238 : find_case_label_for_value (const gswitch *switch_stmt, tree val)
    2504              : {
    2505        23238 :   size_t low, high, n = gimple_switch_num_labels (switch_stmt);
    2506        23238 :   tree default_case = gimple_switch_default_label (switch_stmt);
    2507              : 
    2508        71719 :   for (low = 0, high = n; high - low > 1; )
    2509              :     {
    2510        44864 :       size_t i = (high + low) / 2;
    2511        44864 :       tree t = gimple_switch_label (switch_stmt, i);
    2512        44864 :       int cmp;
    2513              : 
    2514              :       /* Cache the result of comparing CASE_LOW and val.  */
    2515        44864 :       cmp = tree_int_cst_compare (CASE_LOW (t), val);
    2516              : 
    2517        44864 :       if (cmp > 0)
    2518              :         high = i;
    2519              :       else
    2520        33687 :         low = i;
    2521              : 
    2522        44864 :       if (CASE_HIGH (t) == NULL)
    2523              :         {
    2524              :           /* A single-valued case label.  */
    2525        43793 :           if (cmp == 0)
    2526              :             return t;
    2527              :         }
    2528              :       else
    2529              :         {
    2530              :           /* A case range.  We can only handle integer ranges.  */
    2531         1071 :           if (cmp <= 0 && tree_int_cst_compare (CASE_HIGH (t), val) >= 0)
    2532              :             return t;
    2533              :         }
    2534              :     }
    2535              : 
    2536              :   return default_case;
    2537              : }
    2538              : 
    2539              : 
    2540              : /* Dump a basic block on stderr.  */
    2541              : 
    2542              : void
    2543            0 : gimple_debug_bb (basic_block bb)
    2544              : {
    2545            0 :   dump_bb (stderr, bb, 0, TDF_VOPS|TDF_MEMSYMS|TDF_BLOCKS);
    2546            0 : }
    2547              : 
    2548              : 
    2549              : /* Dump basic block with index N on stderr.  */
    2550              : 
    2551              : basic_block
    2552            0 : gimple_debug_bb_n (int n)
    2553              : {
    2554            0 :   gimple_debug_bb (BASIC_BLOCK_FOR_FN (cfun, n));
    2555            0 :   return BASIC_BLOCK_FOR_FN (cfun, n);
    2556              : }
    2557              : 
    2558              : 
    2559              : /* Dump the CFG on stderr.
    2560              : 
    2561              :    FLAGS are the same used by the tree dumping functions
    2562              :    (see TDF_* in dumpfile.h).  */
    2563              : 
    2564              : void
    2565            0 : gimple_debug_cfg (dump_flags_t flags)
    2566              : {
    2567            0 :   gimple_dump_cfg (stderr, flags);
    2568            0 : }
    2569              : 
    2570              : 
    2571              : /* Dump the program showing basic block boundaries on the given FILE.
    2572              : 
    2573              :    FLAGS are the same used by the tree dumping functions (see TDF_* in
    2574              :    tree.h).  */
    2575              : 
    2576              : void
    2577          204 : gimple_dump_cfg (FILE *file, dump_flags_t flags)
    2578              : {
    2579          204 :   if (flags & TDF_DETAILS)
    2580              :     {
    2581            2 :       dump_function_header (file, current_function_decl, flags);
    2582            2 :       fprintf (file, ";; \n%d basic blocks, %d edges, last basic block %d.\n\n",
    2583              :                n_basic_blocks_for_fn (cfun), n_edges_for_fn (cfun),
    2584            2 :                last_basic_block_for_fn (cfun));
    2585              : 
    2586            2 :       brief_dump_cfg (file, flags);
    2587            2 :       fprintf (file, "\n");
    2588              :     }
    2589              : 
    2590          204 :   if (flags & TDF_STATS)
    2591           47 :     dump_cfg_stats (file);
    2592              : 
    2593          204 :   dump_function_to_file (current_function_decl, file, flags | TDF_BLOCKS);
    2594          204 : }
    2595              : 
    2596              : 
    2597              : /* Dump CFG statistics on FILE.  */
    2598              : 
    2599              : void
    2600           47 : dump_cfg_stats (FILE *file)
    2601              : {
    2602           47 :   static long max_num_merged_labels = 0;
    2603           47 :   unsigned long size, total = 0;
    2604           47 :   long num_edges;
    2605           47 :   basic_block bb;
    2606           47 :   const char * const fmt_str   = "%-30s%-13s%12s\n";
    2607           47 :   const char * const fmt_str_1 = "%-30s%13d" PRsa (11) "\n";
    2608           47 :   const char * const fmt_str_2 = "%-30s%13ld" PRsa (11) "\n";
    2609           47 :   const char * const fmt_str_3 = "%-43s" PRsa (11) "\n";
    2610           47 :   const char *funcname = current_function_name ();
    2611              : 
    2612           47 :   fprintf (file, "\nCFG Statistics for %s\n\n", funcname);
    2613              : 
    2614           47 :   fprintf (file, "---------------------------------------------------------\n");
    2615           47 :   fprintf (file, fmt_str, "", "  Number of  ", "Memory");
    2616           47 :   fprintf (file, fmt_str, "", "  instances  ", "used ");
    2617           47 :   fprintf (file, "---------------------------------------------------------\n");
    2618              : 
    2619           47 :   size = n_basic_blocks_for_fn (cfun) * sizeof (struct basic_block_def);
    2620           47 :   total += size;
    2621           47 :   fprintf (file, fmt_str_1, "Basic blocks", n_basic_blocks_for_fn (cfun),
    2622            0 :            SIZE_AMOUNT (size));
    2623              : 
    2624           47 :   num_edges = 0;
    2625          131 :   FOR_EACH_BB_FN (bb, cfun)
    2626          168 :     num_edges += EDGE_COUNT (bb->succs);
    2627           47 :   size = num_edges * sizeof (class edge_def);
    2628           47 :   total += size;
    2629           47 :   fprintf (file, fmt_str_2, "Edges", num_edges, SIZE_AMOUNT (size));
    2630              : 
    2631           47 :   fprintf (file, "---------------------------------------------------------\n");
    2632           47 :   fprintf (file, fmt_str_3, "Total memory used by CFG data",
    2633            0 :            SIZE_AMOUNT (total));
    2634           47 :   fprintf (file, "---------------------------------------------------------\n");
    2635           47 :   fprintf (file, "\n");
    2636              : 
    2637           47 :   if (cfg_stats.num_merged_labels > max_num_merged_labels)
    2638            0 :     max_num_merged_labels = cfg_stats.num_merged_labels;
    2639              : 
    2640           47 :   fprintf (file, "Coalesced label blocks: %ld (Max so far: %ld)\n",
    2641              :            cfg_stats.num_merged_labels, max_num_merged_labels);
    2642              : 
    2643           47 :   fprintf (file, "\n");
    2644           47 : }
    2645              : 
    2646              : 
    2647              : /* Dump CFG statistics on stderr.  Keep extern so that it's always
    2648              :    linked in the final executable.  */
    2649              : 
    2650              : DEBUG_FUNCTION void
    2651            0 : debug_cfg_stats (void)
    2652              : {
    2653            0 :   dump_cfg_stats (stderr);
    2654            0 : }
    2655              : 
    2656              : /*---------------------------------------------------------------------------
    2657              :                              Miscellaneous helpers
    2658              : ---------------------------------------------------------------------------*/
    2659              : 
    2660              : /* Return true if T, a GIMPLE_CALL, can make an abnormal transfer of control
    2661              :    flow.  Transfers of control flow associated with EH are excluded.  */
    2662              : 
    2663              : static bool
    2664    148245496 : call_can_make_abnormal_goto (gimple *t)
    2665              : {
    2666              :   /* If the function has no non-local labels, then a call cannot make an
    2667              :      abnormal transfer of control.  */
    2668    148245496 :   if (!cfun->has_nonlocal_label
    2669    148132293 :       && !cfun->calls_setjmp)
    2670              :    return false;
    2671              : 
    2672              :   /* Likewise if the call has no side effects.  */
    2673       225564 :   if (!gimple_has_side_effects (t))
    2674              :     return false;
    2675              : 
    2676              :   /* Likewise if the called function is leaf.  */
    2677       217385 :   if (gimple_call_flags (t) & ECF_LEAF)
    2678        51886 :     return false;
    2679              : 
    2680              :   return true;
    2681              : }
    2682              : 
    2683              : 
    2684              : /* Return true if T can make an abnormal transfer of control flow.
    2685              :    Transfers of control flow associated with EH are excluded.  */
    2686              : 
    2687              : bool
    2688    638495628 : stmt_can_make_abnormal_goto (gimple *t)
    2689              : {
    2690    638495628 :   if (computed_goto_p (t))
    2691              :     return true;
    2692    638491645 :   if (is_gimple_call (t))
    2693    136840221 :     return call_can_make_abnormal_goto (t);
    2694              :   return false;
    2695              : }
    2696              : 
    2697              : 
    2698              : /* Return true if T represents a stmt that always transfers control.  */
    2699              : 
    2700              : bool
    2701  17794981074 : is_ctrl_stmt (gimple *t)
    2702              : {
    2703  17794981074 :   switch (gimple_code (t))
    2704              :     {
    2705              :     case GIMPLE_COND:
    2706              :     case GIMPLE_SWITCH:
    2707              :     case GIMPLE_GOTO:
    2708              :     case GIMPLE_RETURN:
    2709              :     case GIMPLE_RESX:
    2710              :       return true;
    2711  15523518963 :     default:
    2712  15523518963 :       return false;
    2713              :     }
    2714              : }
    2715              : 
    2716              : 
    2717              : /* Return true if T is a statement that may alter the flow of control
    2718              :    (e.g., a call to a non-returning function).  */
    2719              : 
    2720              : bool
    2721  14794878114 : is_ctrl_altering_stmt (gimple *t)
    2722              : {
    2723  14794878114 :   gcc_assert (t);
    2724              : 
    2725  14794878114 :   switch (gimple_code (t))
    2726              :     {
    2727   1121849860 :     case GIMPLE_CALL:
    2728              :       /* Per stmt call flag indicates whether the call could alter
    2729              :          controlflow.  */
    2730   1121849860 :       if (gimple_call_ctrl_altering_p (t))
    2731              :         return true;
    2732              :       break;
    2733              : 
    2734              :     case GIMPLE_EH_DISPATCH:
    2735              :       /* EH_DISPATCH branches to the individual catch handlers at
    2736              :          this level of a try or allowed-exceptions region.  It can
    2737              :          fallthru to the next statement as well.  */
    2738              :       return true;
    2739              : 
    2740     12850956 :     case GIMPLE_ASM:
    2741     12850956 :       if (gimple_asm_nlabels (as_a <gasm *> (t)) > 0)
    2742              :         return true;
    2743              :       break;
    2744              : 
    2745              :     CASE_GIMPLE_OMP:
    2746              :       /* OpenMP directives alter control flow.  */
    2747              :       return true;
    2748              : 
    2749              :     case GIMPLE_TRANSACTION:
    2750              :       /* A transaction start alters control flow.  */
    2751              :       return true;
    2752              : 
    2753              :     default:
    2754              :       break;
    2755              :     }
    2756              : 
    2757              :   /* If a statement can throw, it alters control flow.  */
    2758  14619118945 :   return stmt_can_throw_internal (cfun, t);
    2759              : }
    2760              : 
    2761              : 
    2762              : /* Return true if T is a simple local goto.  */
    2763              : 
    2764              : bool
    2765      6360553 : simple_goto_p (gimple *t)
    2766              : {
    2767      6360553 :   return (gimple_code (t) == GIMPLE_GOTO
    2768      6360553 :           && TREE_CODE (gimple_goto_dest (t)) == LABEL_DECL);
    2769              : }
    2770              : 
    2771              : 
    2772              : /* Return true if STMT should start a new basic block.  PREV_STMT is
    2773              :    the statement preceding STMT.  It is used when STMT is a label or a
    2774              :    case label.  Labels should only start a new basic block if their
    2775              :    previous statement wasn't a label.  Otherwise, sequence of labels
    2776              :    would generate unnecessary basic blocks that only contain a single
    2777              :    label.  */
    2778              : 
    2779              : static inline bool
    2780     73173701 : stmt_starts_bb_p (gimple *stmt, gimple *prev_stmt)
    2781              : {
    2782     73173701 :   if (stmt == NULL)
    2783              :     return false;
    2784              : 
    2785              :   /* PREV_STMT is only set to a debug stmt if the debug stmt is before
    2786              :      any nondebug stmts in the block.  We don't want to start another
    2787              :      block in this case: the debug stmt will already have started the
    2788              :      one STMT would start if we weren't outputting debug stmts.  */
    2789     73173701 :   if (prev_stmt && is_gimple_debug (prev_stmt))
    2790              :     return false;
    2791              : 
    2792              :   /* Labels start a new basic block only if the preceding statement
    2793              :      wasn't a label of the same type.  This prevents the creation of
    2794              :      consecutive blocks that have nothing but a single label.  */
    2795     72717385 :   if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
    2796              :     {
    2797              :       /* Nonlocal and computed GOTO targets always start a new block.  */
    2798      4168624 :       if (DECL_NONLOCAL (gimple_label_label (label_stmt))
    2799      4168624 :           || FORCED_LABEL (gimple_label_label (label_stmt)))
    2800              :         return true;
    2801              : 
    2802      4154849 :       if (glabel *plabel = safe_dyn_cast <glabel *> (prev_stmt))
    2803              :         {
    2804      2260473 :           if (DECL_NONLOCAL (gimple_label_label (plabel))
    2805      2260473 :               || !DECL_ARTIFICIAL (gimple_label_label (plabel)))
    2806              :             return true;
    2807              : 
    2808      2249056 :           cfg_stats.num_merged_labels++;
    2809      2249056 :           return false;
    2810              :         }
    2811              :       else
    2812              :         return true;
    2813              :     }
    2814     68548761 :   else if (gimple_code (stmt) == GIMPLE_CALL)
    2815              :     {
    2816      9608689 :       if (gimple_call_flags (stmt) & ECF_RETURNS_TWICE)
    2817              :         /* setjmp acts similar to a nonlocal GOTO target and thus should
    2818              :            start a new block.  */
    2819              :         return true;
    2820      9607495 :       if (gimple_call_internal_p (stmt, IFN_PHI)
    2821            0 :           && prev_stmt
    2822            0 :           && gimple_code (prev_stmt) != GIMPLE_LABEL
    2823      9607495 :           && (gimple_code (prev_stmt) != GIMPLE_CALL
    2824            0 :               || ! gimple_call_internal_p (prev_stmt, IFN_PHI)))
    2825              :         /* PHI nodes start a new block unless preceded by a label
    2826              :            or another PHI.  */
    2827            0 :         return true;
    2828              :     }
    2829              : 
    2830              :   return false;
    2831              : }
    2832              : 
    2833              : 
    2834              : /* Return true if T should end a basic block.  */
    2835              : 
    2836              : bool
    2837  15766406904 : stmt_ends_bb_p (gimple *t)
    2838              : {
    2839  15766406904 :   return is_ctrl_stmt (t) || is_ctrl_altering_stmt (t);
    2840              : }
    2841              : 
    2842              : /* Remove block annotations and other data structures.  */
    2843              : 
    2844              : void
    2845      3323965 : delete_tree_cfg_annotations (struct function *fn)
    2846              : {
    2847      3323965 :   vec_free (label_to_block_map_for_fn (fn));
    2848      3323965 : }
    2849              : 
    2850              : /* Return the virtual phi in BB.  */
    2851              : 
    2852              : gphi *
    2853   2839718920 : get_virtual_phi (basic_block bb)
    2854              : {
    2855   2839718920 :   for (gphi_iterator gsi = gsi_start_phis (bb);
    2856   3511449446 :        !gsi_end_p (gsi);
    2857    671730526 :        gsi_next (&gsi))
    2858              :     {
    2859   1509948268 :       gphi *phi = gsi.phi ();
    2860              : 
    2861   3019896536 :       if (virtual_operand_p (PHI_RESULT (phi)))
    2862    838217742 :         return phi;
    2863              :     }
    2864              : 
    2865   2001501178 :   return NULL;
    2866              : }
    2867              : 
    2868              : /* Return the first statement in basic block BB.  */
    2869              : 
    2870              : gimple *
    2871    153575446 : first_stmt (basic_block bb)
    2872              : {
    2873    153575446 :   gimple_stmt_iterator i = gsi_start_bb (bb);
    2874    153575446 :   gimple *stmt = NULL;
    2875              : 
    2876    575342232 :   while (!gsi_end_p (i) && is_gimple_debug ((stmt = gsi_stmt (i))))
    2877              :     {
    2878    421766786 :       gsi_next (&i);
    2879    421766786 :       stmt = NULL;
    2880              :     }
    2881    153575446 :   return stmt;
    2882              : }
    2883              : 
    2884              : /* Return the last statement in basic block BB.  */
    2885              : 
    2886              : gimple *
    2887    178344906 : last_nondebug_stmt (basic_block bb)
    2888              : {
    2889    178344906 :   gimple_stmt_iterator i = gsi_last_bb (bb);
    2890    178344906 :   gimple *stmt = NULL;
    2891              : 
    2892    228263804 :   while (!gsi_end_p (i) && is_gimple_debug ((stmt = gsi_stmt (i))))
    2893              :     {
    2894     49918898 :       gsi_prev (&i);
    2895     49918898 :       stmt = NULL;
    2896              :     }
    2897    178344906 :   return stmt;
    2898              : }
    2899              : 
    2900              : /* Return the last statement of an otherwise empty block.  Return NULL
    2901              :    if the block is totally empty, or if it contains more than one
    2902              :    statement.  */
    2903              : 
    2904              : gimple *
    2905      9463777 : last_and_only_stmt (basic_block bb)
    2906              : {
    2907      9463777 :   gimple_stmt_iterator i = gsi_last_nondebug_bb (bb);
    2908      9463777 :   gimple *last, *prev;
    2909              : 
    2910      9463777 :   if (gsi_end_p (i))
    2911              :     return NULL;
    2912              : 
    2913      9264849 :   last = gsi_stmt (i);
    2914      9264849 :   gsi_prev_nondebug (&i);
    2915      9264849 :   if (gsi_end_p (i))
    2916              :     return last;
    2917              : 
    2918              :   /* Empty statements should no longer appear in the instruction stream.
    2919              :      Everything that might have appeared before should be deleted by
    2920              :      remove_useless_stmts, and the optimizers should just gsi_remove
    2921              :      instead of smashing with build_empty_stmt.
    2922              : 
    2923              :      Thus the only thing that should appear here in a block containing
    2924              :      one executable statement is a label.  */
    2925      7844708 :   prev = gsi_stmt (i);
    2926      7844708 :   if (gimple_code (prev) == GIMPLE_LABEL)
    2927              :     return last;
    2928              :   else
    2929      7762709 :     return NULL;
    2930              : }
    2931              : 
    2932              : /* Returns the basic block after which the new basic block created
    2933              :    by splitting edge EDGE_IN should be placed.  Tries to keep the new block
    2934              :    near its "logical" location.  This is of most help to humans looking
    2935              :    at debugging dumps.  */
    2936              : 
    2937              : basic_block
    2938     27389281 : split_edge_bb_loc (edge edge_in)
    2939              : {
    2940     27389281 :   basic_block dest = edge_in->dest;
    2941     27389281 :   basic_block dest_prev = dest->prev_bb;
    2942              : 
    2943     27389281 :   if (dest_prev)
    2944              :     {
    2945     27389281 :       edge e = find_edge (dest_prev, dest);
    2946     27389281 :       if (e && !(e->flags & EDGE_COMPLEX))
    2947     23151090 :         return edge_in->src;
    2948              :     }
    2949              :   return dest_prev;
    2950              : }
    2951              : 
    2952              : /* Split a (typically critical) edge EDGE_IN.  Return the new block.
    2953              :    Abort on abnormal edges.  */
    2954              : 
    2955              : static basic_block
    2956     25469955 : gimple_split_edge (edge edge_in)
    2957              : {
    2958     25469955 :   basic_block new_bb, after_bb, dest;
    2959     25469955 :   edge new_edge, e;
    2960              : 
    2961              :   /* Abnormal edges cannot be split.  */
    2962     25469955 :   gcc_assert (!(edge_in->flags & EDGE_ABNORMAL));
    2963              : 
    2964     25469955 :   dest = edge_in->dest;
    2965              : 
    2966     25469955 :   after_bb = split_edge_bb_loc (edge_in);
    2967              : 
    2968     25469955 :   new_bb = create_empty_bb (after_bb);
    2969     25469955 :   new_bb->count = edge_in->count ();
    2970     25469955 :   if (coverage_suppressed_p (after_bb))
    2971           73 :     suppress_coverage (new_bb);
    2972              : 
    2973              :   /* We want to avoid re-allocating PHIs when we first
    2974              :      add the fallthru edge from new_bb to dest but we also
    2975              :      want to avoid changing PHI argument order when
    2976              :      first redirecting edge_in away from dest.  The former
    2977              :      avoids changing PHI argument order by adding them
    2978              :      last and then the redirection swapping it back into
    2979              :      place by means of unordered remove.
    2980              :      So hack around things by temporarily removing all PHIs
    2981              :      from the destination during the edge redirection and then
    2982              :      making sure the edges stay in order.  */
    2983     25469955 :   gimple_seq saved_phis = phi_nodes (dest);
    2984     25469955 :   unsigned old_dest_idx = edge_in->dest_idx;
    2985     25469955 :   set_phi_nodes (dest, NULL);
    2986     25469955 :   new_edge = make_single_succ_edge (new_bb, dest, EDGE_FALLTHRU);
    2987     25469955 :   e = redirect_edge_and_branch (edge_in, new_bb);
    2988     25469955 :   gcc_assert (e == edge_in && new_edge->dest_idx == old_dest_idx);
    2989              :   /* set_phi_nodes sets the BB of the PHI nodes, so do it manually here.  */
    2990     25469955 :   dest->il.gimple.phi_nodes = saved_phis;
    2991              : 
    2992     25469955 :   return new_bb;
    2993              : }
    2994              : 
    2995              : 
    2996              : /* Verify properties of the address expression T whose base should be
    2997              :    TREE_ADDRESSABLE if VERIFY_ADDRESSABLE is true.  */
    2998              : 
    2999              : static bool
    3000    627425164 : verify_address (tree t, bool verify_addressable)
    3001              : {
    3002    627425164 :   bool old_constant;
    3003    627425164 :   bool old_side_effects;
    3004    627425164 :   bool new_constant;
    3005    627425164 :   bool new_side_effects;
    3006              : 
    3007    627425164 :   old_constant = TREE_CONSTANT (t);
    3008    627425164 :   old_side_effects = TREE_SIDE_EFFECTS (t);
    3009              : 
    3010    627425164 :   recompute_tree_invariant_for_addr_expr (t);
    3011    627425164 :   new_side_effects = TREE_SIDE_EFFECTS (t);
    3012    627425164 :   new_constant = TREE_CONSTANT (t);
    3013              : 
    3014    627425164 :   if (old_constant != new_constant)
    3015              :     {
    3016            0 :       error ("constant not recomputed when %<ADDR_EXPR%> changed");
    3017            0 :       return true;
    3018              :     }
    3019    627425164 :   if (old_side_effects != new_side_effects)
    3020              :     {
    3021            0 :       error ("side effects not recomputed when %<ADDR_EXPR%> changed");
    3022            0 :       return true;
    3023              :     }
    3024              : 
    3025    627425164 :   tree base = TREE_OPERAND (t, 0);
    3026    777597195 :   while (handled_component_p (base))
    3027    150172031 :     base = TREE_OPERAND (base, 0);
    3028              : 
    3029    627425164 :   if (!(VAR_P (base)
    3030              :         || TREE_CODE (base) == PARM_DECL
    3031              :         || TREE_CODE (base) == RESULT_DECL))
    3032              :     return false;
    3033              : 
    3034    457425861 :   if (verify_addressable && !TREE_ADDRESSABLE (base))
    3035              :     {
    3036            0 :       error ("address taken but %<TREE_ADDRESSABLE%> bit not set");
    3037            0 :       return true;
    3038              :     }
    3039              : 
    3040              :   return false;
    3041              : }
    3042              : 
    3043              : 
    3044              : /* Verify if EXPR is a valid GIMPLE reference expression.  If
    3045              :    REQUIRE_LVALUE is true verifies it is an lvalue.  Returns true
    3046              :    if there is an error, otherwise false.  */
    3047              : 
    3048              : static bool
    3049   3799422033 : verify_types_in_gimple_reference (tree expr, bool require_lvalue)
    3050              : {
    3051   3799422033 :   const char *code_name = get_tree_code_name (TREE_CODE (expr));
    3052              : 
    3053   3799422033 :   if (TREE_CODE (expr) == REALPART_EXPR
    3054   3799422033 :       || TREE_CODE (expr) == IMAGPART_EXPR
    3055   3761785917 :       || TREE_CODE (expr) == BIT_FIELD_REF
    3056   3746314807 :       || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
    3057              :     {
    3058     97863702 :       tree op = TREE_OPERAND (expr, 0);
    3059     97863702 :       if (TREE_CODE (expr) != VIEW_CONVERT_EXPR
    3060     97863702 :           && !is_gimple_reg_type (TREE_TYPE (expr)))
    3061              :         {
    3062            0 :           error ("non-scalar %qs", code_name);
    3063            0 :           return true;
    3064              :         }
    3065              : 
    3066     97863702 :       if (TREE_CODE (expr) == BIT_FIELD_REF)
    3067              :         {
    3068     15471110 :           tree t1 = TREE_OPERAND (expr, 1);
    3069     15471110 :           tree t2 = TREE_OPERAND (expr, 2);
    3070     15471110 :           poly_uint64 size, bitpos;
    3071     15471110 :           if (!poly_int_tree_p (t1, &size)
    3072     15471110 :               || !poly_int_tree_p (t2, &bitpos)
    3073     15471110 :               || !types_compatible_p (bitsizetype, TREE_TYPE (t1))
    3074     30942220 :               || !types_compatible_p (bitsizetype, TREE_TYPE (t2)))
    3075              :             {
    3076            0 :               error ("invalid position or size operand to %qs", code_name);
    3077            0 :               return true;
    3078              :             }
    3079     30902302 :           if (INTEGRAL_TYPE_P (TREE_TYPE (expr))
    3080     28505684 :               && maybe_ne (TYPE_PRECISION (TREE_TYPE (expr)), size))
    3081              :             {
    3082            0 :               error ("integral result type precision does not match "
    3083              :                      "field size of %qs", code_name);
    3084            0 :               return true;
    3085              :             }
    3086     15471110 :           else if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
    3087      2396618 :                    && TYPE_MODE (TREE_TYPE (expr)) != BLKmode
    3088      4790428 :                    && maybe_ne (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr))),
    3089              :                                 size))
    3090              :             {
    3091            0 :               error ("mode size of non-integral result does not "
    3092              :                      "match field size of %qs",
    3093              :                      code_name);
    3094            0 :               return true;
    3095              :             }
    3096     30941520 :           if (INTEGRAL_TYPE_P (TREE_TYPE (op))
    3097     15698782 :               && !type_has_mode_precision_p (TREE_TYPE (op)))
    3098              :             {
    3099            0 :               error ("%qs of non-mode-precision operand", code_name);
    3100            0 :               return true;
    3101              :             }
    3102     15471110 :           if (!AGGREGATE_TYPE_P (TREE_TYPE (op))
    3103     15471110 :               && known_gt (size + bitpos,
    3104              :                            tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (op)))))
    3105              :             {
    3106            0 :               error ("position plus size exceeds size of referenced object in "
    3107              :                      "%qs", code_name);
    3108            0 :               return true;
    3109              :             }
    3110              :         }
    3111              : 
    3112     97863702 :       if ((TREE_CODE (expr) == REALPART_EXPR
    3113     97863702 :            || TREE_CODE (expr) == IMAGPART_EXPR)
    3114    135499818 :           && !useless_type_conversion_p (TREE_TYPE (expr),
    3115     37636116 :                                          TREE_TYPE (TREE_TYPE (op))))
    3116              :         {
    3117            0 :           error ("type mismatch in %qs reference", code_name);
    3118            0 :           debug_generic_stmt (TREE_TYPE (expr));
    3119            0 :           debug_generic_stmt (TREE_TYPE (TREE_TYPE (op)));
    3120            0 :           return true;
    3121              :         }
    3122              : 
    3123     97863702 :       if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
    3124              :         {
    3125              :           /* For VIEW_CONVERT_EXPRs which are allowed here too, we only check
    3126              :              that their operand is not a register an invariant when
    3127              :              requiring an lvalue (this usually means there is a SRA or IPA-SRA
    3128              :              bug).  Otherwise there is nothing to verify, gross mismatches at
    3129              :              most invoke undefined behavior.  */
    3130     44756476 :           if (require_lvalue
    3131     44756476 :               && (is_gimple_reg (op) || is_gimple_min_invariant (op)))
    3132              :             {
    3133            0 :               error ("conversion of %qs on the left hand side of %qs",
    3134            0 :                      get_tree_code_name (TREE_CODE (op)), code_name);
    3135            0 :               debug_generic_stmt (expr);
    3136            0 :               return true;
    3137              :             }
    3138     44756476 :           else if (is_gimple_reg (op)
    3139     44756476 :                    && TYPE_SIZE (TREE_TYPE (expr)) != TYPE_SIZE (TREE_TYPE (op)))
    3140              :             {
    3141            0 :               error ("conversion of register to a different size in %qs",
    3142              :                      code_name);
    3143            0 :               debug_generic_stmt (expr);
    3144            0 :               return true;
    3145              :             }
    3146              :         }
    3147              : 
    3148              :       expr = op;
    3149              :     }
    3150              : 
    3151   3799422033 :   bool require_non_reg = false;
    3152   6201241593 :   while (handled_component_p (expr))
    3153              :     {
    3154   2401819560 :       require_non_reg = true;
    3155   2401819560 :       code_name = get_tree_code_name (TREE_CODE (expr));
    3156              : 
    3157   2401819560 :       if (TREE_CODE (expr) == REALPART_EXPR
    3158   2401819560 :           || TREE_CODE (expr) == IMAGPART_EXPR
    3159   2401819560 :           || TREE_CODE (expr) == BIT_FIELD_REF)
    3160              :         {
    3161            0 :           error ("non-top-level %qs", code_name);
    3162            0 :           return true;
    3163              :         }
    3164              : 
    3165   2401819560 :       tree op = TREE_OPERAND (expr, 0);
    3166              : 
    3167   2401819560 :       if (TREE_CODE (expr) == ARRAY_REF
    3168   2401819560 :           || TREE_CODE (expr) == ARRAY_RANGE_REF)
    3169              :         {
    3170    443382651 :           if (!is_gimple_val (TREE_OPERAND (expr, 1))
    3171    443382651 :               || (TREE_OPERAND (expr, 2)
    3172      3693816 :                   && !is_gimple_val (TREE_OPERAND (expr, 2)))
    3173    886765302 :               || (TREE_OPERAND (expr, 3)
    3174       700366 :                   && !is_gimple_val (TREE_OPERAND (expr, 3))))
    3175              :             {
    3176            0 :               error ("invalid operands to %qs", code_name);
    3177            0 :               debug_generic_stmt (expr);
    3178            0 :               return true;
    3179              :             }
    3180              :         }
    3181              : 
    3182              :       /* Verify if the reference array element types are compatible.  */
    3183   2401819560 :       if (TREE_CODE (expr) == ARRAY_REF
    3184   2844900004 :           && !useless_type_conversion_p (TREE_TYPE (expr),
    3185    443080444 :                                          TREE_TYPE (TREE_TYPE (op))))
    3186              :         {
    3187            0 :           error ("type mismatch in %qs", code_name);
    3188            0 :           debug_generic_stmt (TREE_TYPE (expr));
    3189            0 :           debug_generic_stmt (TREE_TYPE (TREE_TYPE (op)));
    3190            0 :           return true;
    3191              :         }
    3192   2401819560 :       if (TREE_CODE (expr) == ARRAY_RANGE_REF
    3193   2402121767 :           && !useless_type_conversion_p (TREE_TYPE (TREE_TYPE (expr)),
    3194       302207 :                                          TREE_TYPE (TREE_TYPE (op))))
    3195              :         {
    3196            0 :           error ("type mismatch in %qs", code_name);
    3197            0 :           debug_generic_stmt (TREE_TYPE (TREE_TYPE (expr)));
    3198            0 :           debug_generic_stmt (TREE_TYPE (TREE_TYPE (op)));
    3199            0 :           return true;
    3200              :         }
    3201              : 
    3202   2401819560 :       if (TREE_CODE (expr) == COMPONENT_REF)
    3203              :         {
    3204   1955871334 :           if (TREE_OPERAND (expr, 2)
    3205   1955871334 :               && !is_gimple_val (TREE_OPERAND (expr, 2)))
    3206              :             {
    3207            0 :               error ("invalid %qs offset operator", code_name);
    3208            0 :               return true;
    3209              :             }
    3210   1955871334 :           if (!useless_type_conversion_p (TREE_TYPE (expr),
    3211   1955871334 :                                           TREE_TYPE (TREE_OPERAND (expr, 1))))
    3212              :             {
    3213            0 :               error ("type mismatch in %qs", code_name);
    3214            0 :               debug_generic_stmt (TREE_TYPE (expr));
    3215            0 :               debug_generic_stmt (TREE_TYPE (TREE_OPERAND (expr, 1)));
    3216            0 :               return true;
    3217              :             }
    3218              :         }
    3219              : 
    3220   2401819560 :       expr = op;
    3221              :     }
    3222              : 
    3223   3799422033 :   code_name = get_tree_code_name (TREE_CODE (expr));
    3224              : 
    3225   3799422033 :   if (TREE_CODE (expr) == MEM_REF)
    3226              :     {
    3227   1292676371 :       if (!is_gimple_mem_ref_addr (TREE_OPERAND (expr, 0))
    3228   1292676371 :           || (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR
    3229    352983019 :               && verify_address (TREE_OPERAND (expr, 0), false)))
    3230              :         {
    3231            0 :           error ("invalid address operand in %qs", code_name);
    3232            0 :           debug_generic_stmt (expr);
    3233            0 :           return true;
    3234              :         }
    3235   1292676371 :       if (!poly_int_tree_p (TREE_OPERAND (expr, 1))
    3236   1292676371 :           || !POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 1))))
    3237              :         {
    3238            0 :           error ("invalid offset operand in %qs", code_name);
    3239            0 :           debug_generic_stmt (expr);
    3240            0 :           return true;
    3241              :         }
    3242   1292676371 :       if (MR_DEPENDENCE_CLIQUE (expr) != 0
    3243   1292676371 :           && MR_DEPENDENCE_CLIQUE (expr) > cfun->last_clique)
    3244              :         {
    3245            0 :           error ("invalid clique in %qs", code_name);
    3246            0 :           debug_generic_stmt (expr);
    3247            0 :           return true;
    3248              :         }
    3249              :     }
    3250   2506745662 :   else if (TREE_CODE (expr) == TARGET_MEM_REF)
    3251              :     {
    3252     29493816 :       if (!TMR_BASE (expr)
    3253     29493816 :           || !is_gimple_mem_ref_addr (TMR_BASE (expr))
    3254     58987632 :           || (TREE_CODE (TMR_BASE (expr)) == ADDR_EXPR
    3255      6456277 :               && verify_address (TMR_BASE (expr), false)))
    3256              :         {
    3257            0 :           error ("invalid address operand in %qs", code_name);
    3258            0 :           return true;
    3259              :         }
    3260     29493816 :       if (!TMR_OFFSET (expr)
    3261     29493816 :           || !poly_int_tree_p (TMR_OFFSET (expr))
    3262     58987632 :           || !POINTER_TYPE_P (TREE_TYPE (TMR_OFFSET (expr))))
    3263              :         {
    3264            0 :           error ("invalid offset operand in %qs", code_name);
    3265            0 :           debug_generic_stmt (expr);
    3266            0 :           return true;
    3267              :         }
    3268     29493816 :       if (MR_DEPENDENCE_CLIQUE (expr) != 0
    3269     29493816 :           && MR_DEPENDENCE_CLIQUE (expr) > cfun->last_clique)
    3270              :         {
    3271            0 :           error ("invalid clique in %qs", code_name);
    3272            0 :           debug_generic_stmt (expr);
    3273            0 :           return true;
    3274              :         }
    3275              :     }
    3276   2477251846 :   else if (INDIRECT_REF_P (expr))
    3277              :     {
    3278            0 :       error ("%qs in gimple IL", code_name);
    3279            0 :       debug_generic_stmt (expr);
    3280            0 :       return true;
    3281              :     }
    3282   2477251846 :   else if (require_non_reg
    3283   2477251846 :            && (is_gimple_reg (expr)
    3284    914448610 :                || (is_gimple_min_invariant (expr)
    3285              :                    /* STRING_CSTs are representatives of the string table
    3286              :                       entry which lives in memory.  */
    3287      8982901 :                    && TREE_CODE (expr) != STRING_CST)))
    3288              :     {
    3289            0 :       error ("%qs as base where non-register is required", code_name);
    3290            0 :       debug_generic_stmt (expr);
    3291            0 :       return true;
    3292              :     }
    3293              : 
    3294   3799422033 :   if (!require_lvalue
    3295   3799422033 :       && (is_gimple_reg (expr) || is_gimple_min_invariant (expr)))
    3296              :     return false;
    3297              : 
    3298   2572697697 :   if (TREE_CODE (expr) != SSA_NAME && is_gimple_id (expr))
    3299              :     return false;
    3300              : 
    3301   1322170187 :   if (TREE_CODE (expr) != TARGET_MEM_REF
    3302   1322170187 :       && TREE_CODE (expr) != MEM_REF)
    3303              :     {
    3304            0 :       error ("invalid expression for min lvalue");
    3305            0 :       return true;
    3306              :     }
    3307              : 
    3308              :   return false;
    3309              : }
    3310              : 
    3311              : /* Returns true if there is one pointer type in TYPE_POINTER_TO (SRC_OBJ)
    3312              :    list of pointer-to types that is trivially convertible to DEST.  */
    3313              : 
    3314              : static bool
    3315          180 : one_pointer_to_useless_type_conversion_p (tree dest, tree src_obj)
    3316              : {
    3317          180 :   tree src;
    3318              : 
    3319          180 :   if (!TYPE_POINTER_TO (src_obj))
    3320              :     return true;
    3321              : 
    3322          180 :   for (src = TYPE_POINTER_TO (src_obj); src; src = TYPE_NEXT_PTR_TO (src))
    3323          180 :     if (useless_type_conversion_p (dest, src))
    3324              :       return true;
    3325              : 
    3326              :   return false;
    3327              : }
    3328              : 
    3329              : /* Return true if TYPE1 is a fixed-point type and if conversions to and
    3330              :    from TYPE2 can be handled by FIXED_CONVERT_EXPR.  */
    3331              : 
    3332              : static bool
    3333            0 : valid_fixed_convert_types_p (tree type1, tree type2)
    3334              : {
    3335            0 :   return (FIXED_POINT_TYPE_P (type1)
    3336            0 :           && (INTEGRAL_TYPE_P (type2)
    3337            0 :               || SCALAR_FLOAT_TYPE_P (type2)
    3338            0 :               || FIXED_POINT_TYPE_P (type2)));
    3339              : }
    3340              : 
    3341              : /* Verify the contents of a GIMPLE_CALL STMT.  Returns true when there
    3342              :    is a problem, otherwise false.  */
    3343              : 
    3344              : static bool
    3345   1096846793 : verify_gimple_call (gcall *stmt)
    3346              : {
    3347   1096846793 :   tree fn = gimple_call_fn (stmt);
    3348   1096846793 :   tree fntype, fndecl;
    3349   1096846793 :   unsigned i;
    3350              : 
    3351   1096846793 :   if (gimple_call_internal_p (stmt))
    3352              :     {
    3353     41736408 :       if (fn)
    3354              :         {
    3355            0 :           error ("gimple call has two targets");
    3356            0 :           debug_generic_stmt (fn);
    3357            0 :           return true;
    3358              :         }
    3359              :     }
    3360              :   else
    3361              :     {
    3362   1055110385 :       if (!fn)
    3363              :         {
    3364            0 :           error ("gimple call has no target");
    3365            0 :           return true;
    3366              :         }
    3367              :     }
    3368              : 
    3369   1055110385 :   if (fn && !is_gimple_call_addr (fn))
    3370              :     {
    3371            0 :       error ("invalid function in gimple call");
    3372            0 :       debug_generic_stmt (fn);
    3373            0 :       return true;
    3374              :     }
    3375              : 
    3376   1096846793 :   if (fn
    3377   1096846793 :       && (!POINTER_TYPE_P (TREE_TYPE (fn))
    3378   1055110385 :           || (TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) != FUNCTION_TYPE
    3379    179036609 :               && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) != METHOD_TYPE)))
    3380              :     {
    3381            0 :       error ("non-function in gimple call");
    3382            0 :       return true;
    3383              :     }
    3384              : 
    3385   1096846793 :    fndecl = gimple_call_fndecl (stmt);
    3386   1096846793 :    if (fndecl
    3387   1028811659 :        && TREE_CODE (fndecl) == FUNCTION_DECL
    3388   1028811659 :        && DECL_LOOPING_CONST_OR_PURE_P (fndecl)
    3389      6057427 :        && !DECL_PURE_P (fndecl)
    3390   1097217528 :        && !TREE_READONLY (fndecl))
    3391              :      {
    3392            0 :        error ("invalid pure const state for function");
    3393            0 :        return true;
    3394              :      }
    3395              : 
    3396   1096846793 :   tree lhs = gimple_call_lhs (stmt);
    3397   1096846793 :   if (lhs
    3398   1096846793 :       && (!is_gimple_reg (lhs)
    3399     72713779 :           && (!is_gimple_lvalue (lhs)
    3400     72713779 :               || verify_types_in_gimple_reference
    3401     72713779 :                    (TREE_CODE (lhs) == WITH_SIZE_EXPR
    3402            0 :                     ? TREE_OPERAND (lhs, 0) : lhs, true))))
    3403              :     {
    3404            0 :       error ("invalid LHS in gimple call");
    3405            0 :       return true;
    3406              :     }
    3407              : 
    3408   1096846793 :   if (gimple_call_ctrl_altering_p (stmt)
    3409    152436940 :       && gimple_call_noreturn_p (stmt)
    3410   1244187294 :       && should_remove_lhs_p (lhs))
    3411              :     {
    3412            0 :       error ("LHS in %<noreturn%> call");
    3413            0 :       return true;
    3414              :     }
    3415              : 
    3416   1096846793 :   fntype = gimple_call_fntype (stmt);
    3417   1096846793 :   if (fntype
    3418   1096846793 :       && lhs
    3419    398766219 :       && !useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (fntype))
    3420              :       /* ???  At least C++ misses conversions at assignments from
    3421              :          void * call results.
    3422              :          For now simply allow arbitrary pointer type conversions.  */
    3423   1096846793 :       && !(POINTER_TYPE_P (TREE_TYPE (lhs))
    3424            0 :            && POINTER_TYPE_P (TREE_TYPE (fntype))))
    3425              :     {
    3426            0 :       error ("invalid conversion in gimple call");
    3427            0 :       debug_generic_stmt (TREE_TYPE (lhs));
    3428            0 :       debug_generic_stmt (TREE_TYPE (fntype));
    3429            0 :       return true;
    3430              :     }
    3431              : 
    3432   1096846793 :   if (gimple_call_chain (stmt)
    3433   1096846793 :       && !is_gimple_val (gimple_call_chain (stmt)))
    3434              :     {
    3435            0 :       error ("invalid static chain in gimple call");
    3436            0 :       debug_generic_stmt (gimple_call_chain (stmt));
    3437            0 :       return true;
    3438              :     }
    3439              : 
    3440              :   /* If there is a static chain argument, the call should either be
    3441              :      indirect, or the decl should have DECL_STATIC_CHAIN set.  */
    3442   1096846793 :   if (gimple_call_chain (stmt)
    3443      4996689 :       && fndecl
    3444   1098367127 :       && !DECL_STATIC_CHAIN (fndecl))
    3445              :     {
    3446            0 :       error ("static chain with function that doesn%'t use one");
    3447            0 :       return true;
    3448              :     }
    3449              : 
    3450   1096846793 :   if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
    3451              :     {
    3452    257902094 :       switch (DECL_FUNCTION_CODE (fndecl))
    3453              :         {
    3454     27448086 :         case BUILT_IN_UNREACHABLE:
    3455     27448086 :         case BUILT_IN_UNREACHABLE_TRAP:
    3456     27448086 :         case BUILT_IN_TRAP:
    3457     27448086 :           if (gimple_call_num_args (stmt) > 0)
    3458              :             {
    3459              :               /* Built-in unreachable with parameters might not be caught by
    3460              :                  undefined behavior sanitizer.  Front-ends do check users do not
    3461              :                  call them that way but we also produce calls to
    3462              :                  __builtin_unreachable internally, for example when IPA figures
    3463              :                  out a call cannot happen in a legal program.  In such cases,
    3464              :                  we must make sure arguments are stripped off.  */
    3465            0 :               error ("%<__builtin_unreachable%> or %<__builtin_trap%> call "
    3466              :                      "with arguments");
    3467            0 :               return true;
    3468              :             }
    3469              :           break;
    3470              :         default:
    3471              :           break;
    3472              :         }
    3473              :     }
    3474              : 
    3475              :   /* For a call to .DEFERRED_INIT,
    3476              :      LHS = DEFERRED_INIT (SIZE of the DECL, INIT_TYPE, NAME of the DECL)
    3477              :      we should guarantee that when the 1st argument is a constant, it should
    3478              :      be the same as the size of the LHS.  */
    3479              : 
    3480   1096846793 :   if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
    3481              :     {
    3482      9854174 :       tree size_of_arg0 = gimple_call_arg (stmt, 0);
    3483      9854174 :       tree size_of_lhs = TYPE_SIZE_UNIT (TREE_TYPE (lhs));
    3484              : 
    3485      9854174 :       if (TREE_CODE (lhs) == SSA_NAME)
    3486      9854174 :         lhs = SSA_NAME_VAR (lhs);
    3487              : 
    3488      9854174 :       poly_uint64 size_from_arg0, size_from_lhs;
    3489      9854174 :       bool is_constant_size_arg0 = poly_int_tree_p (size_of_arg0,
    3490              :                                                     &size_from_arg0);
    3491      9854174 :       bool is_constant_size_lhs = poly_int_tree_p (size_of_lhs,
    3492              :                                                    &size_from_lhs);
    3493      9854174 :       if (is_constant_size_arg0 && is_constant_size_lhs)
    3494      9843723 :         if (maybe_ne (size_from_arg0, size_from_lhs))
    3495              :           {
    3496            0 :             error ("%<DEFERRED_INIT%> calls should have same "
    3497              :                    "constant size for the first argument and LHS");
    3498            0 :             return true;
    3499              :           }
    3500              :     }
    3501              : 
    3502              :   /* IFN_VARING is not allowed to be present after the completion of any pass
    3503              :      as it should have been replaced.  */
    3504   1096846793 :   if (gimple_call_internal_p (stmt, IFN_VARYING))
    3505              :     {
    3506            0 :       error ("%<.VARYING%> calls should have been replaced and are not allowed "
    3507              :              "outside of the pass that introduced them");
    3508            0 :       return true;
    3509              :     }
    3510              :   /* ???  The C frontend passes unpromoted arguments in case it
    3511              :      didn't see a function declaration before the call.  So for now
    3512              :      leave the call arguments mostly unverified.  Once we gimplify
    3513              :      unit-at-a-time we have a chance to fix this.  */
    3514   3271312638 :   for (i = 0; i < gimple_call_num_args (stmt); ++i)
    3515              :     {
    3516   2174465846 :       tree arg = gimple_call_arg (stmt, i);
    3517   2174465846 :       if ((is_gimple_reg_type (TREE_TYPE (arg))
    3518   2054622416 :            && !is_gimple_val (arg))
    3519   4229088261 :           || (!is_gimple_reg_type (TREE_TYPE (arg))
    3520    119843430 :               && !is_gimple_lvalue (arg)))
    3521              :         {
    3522            1 :           error ("invalid argument to gimple call");
    3523            1 :           debug_generic_expr (arg);
    3524            1 :           return true;
    3525              :         }
    3526   2174465845 :       if (!is_gimple_reg (arg))
    3527              :         {
    3528   1283938191 :           if (TREE_CODE (arg) == WITH_SIZE_EXPR)
    3529        22351 :             arg = TREE_OPERAND (arg, 0);
    3530   1283938191 :           if (verify_types_in_gimple_reference (arg, false))
    3531              :             return true;
    3532              :         }
    3533              :     }
    3534              : 
    3535              :   return false;
    3536              : }
    3537              : 
    3538              : /* Verifies the gimple comparison with the result type TYPE and
    3539              :    the operands OP0 and OP1, comparison code is CODE.  */
    3540              : 
    3541              : static bool
    3542    862399697 : verify_gimple_comparison (tree type, tree op0, tree op1, enum tree_code code)
    3543              : {
    3544    862399697 :   tree op0_type = TREE_TYPE (op0);
    3545    862399697 :   tree op1_type = TREE_TYPE (op1);
    3546              : 
    3547    862399697 :   if (!is_gimple_val (op0) || !is_gimple_val (op1))
    3548              :     {
    3549            0 :       error ("invalid operands in gimple comparison");
    3550            0 :       return true;
    3551              :     }
    3552              : 
    3553              :   /* For comparisons we do not have the operations type as the
    3554              :      effective type the comparison is carried out in.  Instead
    3555              :      we require that either the first operand is trivially
    3556              :      convertible into the second, or the other way around.  */
    3557    862399697 :   if (!useless_type_conversion_p (op0_type, op1_type)
    3558    862399697 :       && !useless_type_conversion_p (op1_type, op0_type))
    3559              :     {
    3560            0 :       error ("mismatching comparison operand types");
    3561            0 :       debug_generic_expr (op0_type);
    3562            0 :       debug_generic_expr (op1_type);
    3563            0 :       return true;
    3564              :     }
    3565              : 
    3566              :   /* The resulting type of a comparison may be an effective boolean type.  */
    3567    862399697 :   if (INTEGRAL_TYPE_P (type)
    3568    862399697 :       && (TREE_CODE (type) == BOOLEAN_TYPE
    3569         1592 :           || TYPE_PRECISION (type) == 1))
    3570              :     {
    3571    860430156 :       if ((VECTOR_TYPE_P (op0_type)
    3572    860327891 :            || VECTOR_TYPE_P (op1_type))
    3573       102265 :           && code != EQ_EXPR && code != NE_EXPR
    3574            0 :           && !VECTOR_BOOLEAN_TYPE_P (op0_type)
    3575    860430156 :           && !VECTOR_INTEGER_TYPE_P (op0_type))
    3576              :         {
    3577            0 :           error ("unsupported operation or type for vector comparison"
    3578              :                  " returning a boolean");
    3579            0 :           debug_generic_expr (op0_type);
    3580            0 :           debug_generic_expr (op1_type);
    3581            0 :           return true;
    3582              :         }
    3583              :     }
    3584              :   /* Or a boolean vector type with the same element count
    3585              :      as the comparison operand types.  */
    3586      1969541 :   else if (VECTOR_TYPE_P (type)
    3587      1969541 :            && TREE_CODE (TREE_TYPE (type)) == BOOLEAN_TYPE)
    3588              :     {
    3589      1969541 :       if (TREE_CODE (op0_type) != VECTOR_TYPE
    3590      1969541 :           || TREE_CODE (op1_type) != VECTOR_TYPE)
    3591              :         {
    3592            0 :           error ("non-vector operands in vector comparison");
    3593            0 :           debug_generic_expr (op0_type);
    3594            0 :           debug_generic_expr (op1_type);
    3595            0 :           return true;
    3596              :         }
    3597              : 
    3598      1969541 :       if (maybe_ne (TYPE_VECTOR_SUBPARTS (type),
    3599      3939082 :                     TYPE_VECTOR_SUBPARTS (op0_type)))
    3600              :         {
    3601            0 :           error ("invalid vector comparison resulting type");
    3602            0 :           debug_generic_expr (type);
    3603            0 :           return true;
    3604              :         }
    3605              :     }
    3606              :   else
    3607              :     {
    3608            0 :       error ("bogus comparison result type");
    3609            0 :       debug_generic_expr (type);
    3610            0 :       return true;
    3611              :     }
    3612              : 
    3613              :   return false;
    3614              : }
    3615              : 
    3616              : /* Verify a gimple assignment statement STMT with an unary rhs.
    3617              :    Returns true if anything is wrong.  */
    3618              : 
    3619              : static bool
    3620    424692850 : verify_gimple_assign_unary (gassign *stmt)
    3621              : {
    3622    424692850 :   enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
    3623    424692850 :   tree lhs = gimple_assign_lhs (stmt);
    3624    424692850 :   tree lhs_type = TREE_TYPE (lhs);
    3625    424692850 :   tree rhs1 = gimple_assign_rhs1 (stmt);
    3626    424692850 :   tree rhs1_type = TREE_TYPE (rhs1);
    3627              : 
    3628    424692850 :   if (!is_gimple_reg (lhs))
    3629              :     {
    3630            0 :       error ("non-register as LHS of unary operation");
    3631            0 :       return true;
    3632              :     }
    3633              : 
    3634    424692850 :   if (!is_gimple_val (rhs1))
    3635              :     {
    3636            0 :       error ("invalid operand in unary operation");
    3637            0 :       return true;
    3638              :     }
    3639              : 
    3640    424692850 :   const char* const code_name = get_tree_code_name (rhs_code);
    3641              : 
    3642              :   /* First handle conversions.  */
    3643    424692850 :   switch (rhs_code)
    3644              :     {
    3645    376601830 :     CASE_CONVERT:
    3646    376601830 :       {
    3647              :         /* Allow conversions between vectors with the same number of elements,
    3648              :            provided that the conversion is OK for the element types too.  */
    3649    376601830 :         if (VECTOR_TYPE_P (lhs_type)
    3650       144470 :             && VECTOR_TYPE_P (rhs1_type)
    3651    376746300 :             && known_eq (TYPE_VECTOR_SUBPARTS (lhs_type),
    3652              :                          TYPE_VECTOR_SUBPARTS (rhs1_type)))
    3653              :           {
    3654       144470 :             lhs_type = TREE_TYPE (lhs_type);
    3655       144470 :             rhs1_type = TREE_TYPE (rhs1_type);
    3656              :           }
    3657    376457360 :         else if (VECTOR_TYPE_P (lhs_type) || VECTOR_TYPE_P (rhs1_type))
    3658              :           {
    3659            0 :             error ("invalid vector types in nop conversion");
    3660            0 :             debug_generic_expr (lhs_type);
    3661            0 :             debug_generic_expr (rhs1_type);
    3662            0 :             return true;
    3663              :           }
    3664              : 
    3665              :         /* Allow conversions from pointer type to integral type only if
    3666              :            there is no sign or zero extension involved.
    3667              :            For targets were the precision of ptrofftype doesn't match that
    3668              :            of pointers we allow conversions to types where
    3669              :            POINTERS_EXTEND_UNSIGNED specifies how that works.  */
    3670    376601830 :         if ((POINTER_TYPE_P (lhs_type)
    3671     23739311 :              && INTEGRAL_TYPE_P (rhs1_type))
    3672    380716207 :             || (POINTER_TYPE_P (rhs1_type)
    3673     47764817 :                 && INTEGRAL_TYPE_P (lhs_type)
    3674     43650440 :                 && (TYPE_PRECISION (rhs1_type) >= TYPE_PRECISION (lhs_type)
    3675              : #if defined(POINTERS_EXTEND_UNSIGNED)
    3676            0 :                     || (TYPE_MODE (rhs1_type) == ptr_mode
    3677            0 :                         && (TYPE_PRECISION (lhs_type)
    3678            0 :                               == BITS_PER_WORD /* word_mode */
    3679            0 :                             || (TYPE_PRECISION (lhs_type)
    3680            0 :                                   == GET_MODE_PRECISION (Pmode))))
    3681              : #endif
    3682              :                    )))
    3683              :           return false;
    3684              : 
    3685              :         /* Allow conversion from integral to offset type and vice versa.  */
    3686    313326456 :         if ((TREE_CODE (lhs_type) == OFFSET_TYPE
    3687         7586 :              && INTEGRAL_TYPE_P (rhs1_type))
    3688    313325300 :             || (INTEGRAL_TYPE_P (lhs_type)
    3689    289164399 :                 && TREE_CODE (rhs1_type) == OFFSET_TYPE))
    3690              :           return false;
    3691              : 
    3692              :         /* Otherwise assert we are converting between types of the
    3693              :            same kind.  */
    3694    313292717 :         if (INTEGRAL_TYPE_P (lhs_type) != INTEGRAL_TYPE_P (rhs1_type))
    3695              :           {
    3696            0 :             error ("invalid types in nop conversion");
    3697            0 :             debug_generic_expr (lhs_type);
    3698            0 :             debug_generic_expr (rhs1_type);
    3699            0 :             return true;
    3700              :           }
    3701              : 
    3702              :         return false;
    3703              :       }
    3704              : 
    3705            0 :     case ADDR_SPACE_CONVERT_EXPR:
    3706            0 :       {
    3707            0 :         if (!POINTER_TYPE_P (rhs1_type) || !POINTER_TYPE_P (lhs_type)
    3708            0 :             || (TYPE_ADDR_SPACE (TREE_TYPE (rhs1_type))
    3709            0 :                 == TYPE_ADDR_SPACE (TREE_TYPE (lhs_type))))
    3710              :           {
    3711            0 :             error ("invalid types in address space conversion");
    3712            0 :             debug_generic_expr (lhs_type);
    3713            0 :             debug_generic_expr (rhs1_type);
    3714            0 :             return true;
    3715              :           }
    3716              : 
    3717              :         return false;
    3718              :       }
    3719              : 
    3720            0 :     case FIXED_CONVERT_EXPR:
    3721            0 :       {
    3722            0 :         if (!valid_fixed_convert_types_p (lhs_type, rhs1_type)
    3723    424692850 :             && !valid_fixed_convert_types_p (rhs1_type, lhs_type))
    3724              :           {
    3725            0 :             error ("invalid types in fixed-point conversion");
    3726            0 :             debug_generic_expr (lhs_type);
    3727            0 :             debug_generic_expr (rhs1_type);
    3728            0 :             return true;
    3729              :           }
    3730              : 
    3731              :         return false;
    3732              :       }
    3733              : 
    3734     16542533 :     case FLOAT_EXPR:
    3735     16542533 :       {
    3736     16448729 :         if ((!INTEGRAL_TYPE_P (rhs1_type) || !SCALAR_FLOAT_TYPE_P (lhs_type))
    3737     16542533 :             && (!VECTOR_INTEGER_TYPE_P (rhs1_type)
    3738        93804 :                 || !VECTOR_FLOAT_TYPE_P (lhs_type)))
    3739              :           {
    3740            0 :             error ("invalid types in conversion to floating-point");
    3741            0 :             debug_generic_expr (lhs_type);
    3742            0 :             debug_generic_expr (rhs1_type);
    3743            0 :             return true;
    3744              :           }
    3745              : 
    3746              :         return false;
    3747              :       }
    3748              : 
    3749      5198992 :     case FIX_TRUNC_EXPR:
    3750      5198992 :       {
    3751      5171808 :         if ((!INTEGRAL_TYPE_P (lhs_type) || !SCALAR_FLOAT_TYPE_P (rhs1_type))
    3752      5198992 :             && (!VECTOR_INTEGER_TYPE_P (lhs_type)
    3753        27184 :                 || !VECTOR_FLOAT_TYPE_P (rhs1_type)))
    3754              :           {
    3755            0 :             error ("invalid types in conversion to integer");
    3756            0 :             debug_generic_expr (lhs_type);
    3757            0 :             debug_generic_expr (rhs1_type);
    3758            0 :             return true;
    3759              :           }
    3760              : 
    3761              :         return false;
    3762              :       }
    3763              : 
    3764       860288 :     case VEC_UNPACK_HI_EXPR:
    3765       860288 :     case VEC_UNPACK_LO_EXPR:
    3766       860288 :     case VEC_UNPACK_FLOAT_HI_EXPR:
    3767       860288 :     case VEC_UNPACK_FLOAT_LO_EXPR:
    3768       860288 :     case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
    3769       860288 :     case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
    3770       860288 :       if (TREE_CODE (rhs1_type) != VECTOR_TYPE
    3771       860288 :           || TREE_CODE (lhs_type) != VECTOR_TYPE
    3772       860288 :           || (!INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
    3773       119298 :               && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type)))
    3774       860288 :           || (!INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
    3775        35144 :               && !SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type)))
    3776       860288 :           || ((rhs_code == VEC_UNPACK_HI_EXPR
    3777       860288 :                || rhs_code == VEC_UNPACK_LO_EXPR)
    3778      1546524 :               && (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
    3779       773262 :                   != INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))))
    3780       860288 :           || ((rhs_code == VEC_UNPACK_FLOAT_HI_EXPR
    3781       860288 :                || rhs_code == VEC_UNPACK_FLOAT_LO_EXPR)
    3782        85590 :               && (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
    3783        85590 :                   || SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type))))
    3784       860288 :           || ((rhs_code == VEC_UNPACK_FIX_TRUNC_HI_EXPR
    3785       860288 :                || rhs_code == VEC_UNPACK_FIX_TRUNC_LO_EXPR)
    3786         1436 :               && (INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
    3787         1436 :                   || SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type))))
    3788      1720576 :           || (maybe_ne (GET_MODE_SIZE (element_mode (lhs_type)),
    3789      1720576 :                         2 * GET_MODE_SIZE (element_mode (rhs1_type)))
    3790        86222 :               && (!VECTOR_BOOLEAN_TYPE_P (lhs_type)
    3791        86222 :                   || !VECTOR_BOOLEAN_TYPE_P (rhs1_type)))
    3792      1720576 :           || maybe_ne (2 * TYPE_VECTOR_SUBPARTS (lhs_type),
    3793      1720576 :                        TYPE_VECTOR_SUBPARTS (rhs1_type)))
    3794              :         {
    3795            0 :           error ("type mismatch in %qs expression", code_name);
    3796            0 :           debug_generic_expr (lhs_type);
    3797            0 :           debug_generic_expr (rhs1_type);
    3798            0 :           return true;
    3799              :         }
    3800              : 
    3801              :       return false;
    3802              : 
    3803       140937 :     case ABSU_EXPR:
    3804        32218 :       if (!ANY_INTEGRAL_TYPE_P (lhs_type)
    3805       140937 :           || !TYPE_UNSIGNED (lhs_type)
    3806       140937 :           || !ANY_INTEGRAL_TYPE_P (rhs1_type)
    3807       140937 :           || TYPE_UNSIGNED (rhs1_type)
    3808       281874 :           || element_precision (lhs_type) != element_precision (rhs1_type))
    3809              :         {
    3810            0 :           error ("invalid types for %qs", code_name);
    3811            0 :           debug_generic_expr (lhs_type);
    3812            0 :           debug_generic_expr (rhs1_type);
    3813            0 :           return true;
    3814              :         }
    3815              :       return false;
    3816              : 
    3817            0 :     case VEC_DUPLICATE_EXPR:
    3818            0 :       if (TREE_CODE (lhs_type) != VECTOR_TYPE
    3819            0 :           || !useless_type_conversion_p (TREE_TYPE (lhs_type), rhs1_type))
    3820              :         {
    3821            0 :           error ("%qs should be from a scalar to a like vector", code_name);
    3822            0 :           debug_generic_expr (lhs_type);
    3823            0 :           debug_generic_expr (rhs1_type);
    3824            0 :           return true;
    3825              :         }
    3826              :       return false;
    3827              : 
    3828        38652 :     case CONJ_EXPR:
    3829        38652 :       if (TREE_CODE (lhs_type) != COMPLEX_TYPE)
    3830              :         {
    3831            0 : diagnose_unary_lhs:
    3832            0 :           error ("invalid type for %qs", code_name);
    3833            0 :           debug_generic_expr (lhs_type);
    3834            0 :           return true;
    3835              :         }
    3836              :       break;
    3837              : 
    3838     24874077 :     case NEGATE_EXPR:
    3839     24874077 :     case ABS_EXPR:
    3840     24874077 :     case BIT_NOT_EXPR:
    3841     24874077 :       if (POINTER_TYPE_P (lhs_type) || TREE_CODE (lhs_type) == OFFSET_TYPE)
    3842            0 :         goto diagnose_unary_lhs;
    3843              :       /* FALLTHRU */
    3844     25309618 :     case PAREN_EXPR:
    3845     25309618 :       if (AGGREGATE_TYPE_P (lhs_type))
    3846            0 :         goto diagnose_unary_lhs;
    3847              :       break;
    3848              : 
    3849            0 :     default:
    3850            0 :       gcc_unreachable ();
    3851              :     }
    3852              : 
    3853              :   /* For the remaining codes assert there is no conversion involved.  */
    3854     25348270 :   if (!useless_type_conversion_p (lhs_type, rhs1_type))
    3855              :     {
    3856            0 :       error ("non-trivial conversion in unary operation");
    3857            0 :       debug_generic_expr (lhs_type);
    3858            0 :       debug_generic_expr (rhs1_type);
    3859            0 :       return true;
    3860              :     }
    3861              : 
    3862              :   return false;
    3863              : }
    3864              : 
    3865              : /* Verify a gimple assignment statement STMT with a binary rhs.
    3866              :    Returns true if anything is wrong.  */
    3867              : 
    3868              : static bool
    3869   1056613735 : verify_gimple_assign_binary (gassign *stmt)
    3870              : {
    3871   1056613735 :   enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
    3872   1056613735 :   tree lhs = gimple_assign_lhs (stmt);
    3873   1056613735 :   tree lhs_type = TREE_TYPE (lhs);
    3874   1056613735 :   tree rhs1 = gimple_assign_rhs1 (stmt);
    3875   1056613735 :   tree rhs1_type = TREE_TYPE (rhs1);
    3876   1056613735 :   tree rhs2 = gimple_assign_rhs2 (stmt);
    3877   1056613735 :   tree rhs2_type = TREE_TYPE (rhs2);
    3878              : 
    3879   1056613735 :   if (!is_gimple_reg (lhs))
    3880              :     {
    3881            0 :       error ("non-register as LHS of binary operation");
    3882            0 :       return true;
    3883              :     }
    3884              : 
    3885   1056613735 :   if (!is_gimple_val (rhs1)
    3886   1056613735 :       || !is_gimple_val (rhs2))
    3887              :     {
    3888            0 :       error ("invalid operands in binary operation");
    3889            0 :       return true;
    3890              :     }
    3891              : 
    3892   1056613735 :   const char* const code_name = get_tree_code_name (rhs_code);
    3893              : 
    3894              :   /* First handle operations that involve different types.  */
    3895   1056613735 :   switch (rhs_code)
    3896              :     {
    3897      2467071 :     case COMPLEX_EXPR:
    3898      2467071 :       {
    3899      2467071 :         if (TREE_CODE (lhs_type) != COMPLEX_TYPE
    3900      2467071 :             || !(INTEGRAL_TYPE_P (rhs1_type)
    3901              :                  || SCALAR_FLOAT_TYPE_P (rhs1_type))
    3902      2467071 :             || !(INTEGRAL_TYPE_P (rhs2_type)
    3903              :                  || SCALAR_FLOAT_TYPE_P (rhs2_type)))
    3904              :           {
    3905            0 :             error ("type mismatch in %qs", code_name);
    3906            0 :             debug_generic_expr (lhs_type);
    3907            0 :             debug_generic_expr (rhs1_type);
    3908            0 :             debug_generic_expr (rhs2_type);
    3909            0 :             return true;
    3910              :           }
    3911              : 
    3912              :         return false;
    3913              :       }
    3914              : 
    3915     33670203 :     case LSHIFT_EXPR:
    3916     33670203 :     case RSHIFT_EXPR:
    3917     33670203 :     case LROTATE_EXPR:
    3918     33670203 :     case RROTATE_EXPR:
    3919     33670203 :       {
    3920              :         /* Shifts and rotates are ok on integral types, fixed point
    3921              :            types and integer vector types.  */
    3922     33670203 :         if ((!INTEGRAL_TYPE_P (rhs1_type)
    3923       731205 :              && !FIXED_POINT_TYPE_P (rhs1_type)
    3924       731205 :              && ! (VECTOR_TYPE_P (rhs1_type)
    3925       731205 :                   && INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))))
    3926     33670203 :             || (!INTEGRAL_TYPE_P (rhs2_type)
    3927              :                 /* Vector shifts of vectors are also ok.  */
    3928       200941 :                 && ! (VECTOR_TYPE_P (rhs1_type)
    3929       200941 :                      && INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
    3930       200941 :                      && VECTOR_TYPE_P (rhs2_type)
    3931       200941 :                      && INTEGRAL_TYPE_P (TREE_TYPE (rhs2_type))))
    3932     67340406 :             || !useless_type_conversion_p (lhs_type, rhs1_type))
    3933              :           {
    3934            0 :             error ("type mismatch in %qs", code_name);
    3935            0 :             debug_generic_expr (lhs_type);
    3936            0 :             debug_generic_expr (rhs1_type);
    3937            0 :             debug_generic_expr (rhs2_type);
    3938            0 :             return true;
    3939              :           }
    3940              : 
    3941              :         return false;
    3942              :       }
    3943              : 
    3944            0 :     case WIDEN_LSHIFT_EXPR:
    3945            0 :       {
    3946            0 :         if (!INTEGRAL_TYPE_P (lhs_type)
    3947            0 :             || !INTEGRAL_TYPE_P (rhs1_type)
    3948            0 :             || TREE_CODE (rhs2) != INTEGER_CST
    3949            0 :             || (2 * TYPE_PRECISION (rhs1_type) > TYPE_PRECISION (lhs_type)))
    3950              :           {
    3951            0 :             error ("type mismatch in %qs", code_name);
    3952            0 :             debug_generic_expr (lhs_type);
    3953            0 :             debug_generic_expr (rhs1_type);
    3954            0 :             debug_generic_expr (rhs2_type);
    3955            0 :             return true;
    3956              :           }
    3957              : 
    3958              :         return false;
    3959              :       }
    3960              : 
    3961            0 :     case VEC_WIDEN_LSHIFT_HI_EXPR:
    3962            0 :     case VEC_WIDEN_LSHIFT_LO_EXPR:
    3963            0 :       {
    3964            0 :         if (TREE_CODE (rhs1_type) != VECTOR_TYPE
    3965            0 :             || TREE_CODE (lhs_type) != VECTOR_TYPE
    3966            0 :             || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
    3967            0 :             || !INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
    3968            0 :             || TREE_CODE (rhs2) != INTEGER_CST
    3969            0 :             || (2 * TYPE_PRECISION (TREE_TYPE (rhs1_type))
    3970            0 :                 > TYPE_PRECISION (TREE_TYPE (lhs_type))))
    3971              :           {
    3972            0 :             error ("type mismatch in %qs", code_name);
    3973            0 :             debug_generic_expr (lhs_type);
    3974            0 :             debug_generic_expr (rhs1_type);
    3975            0 :             debug_generic_expr (rhs2_type);
    3976            0 :             return true;
    3977              :           }
    3978              : 
    3979              :         return false;
    3980              :       }
    3981              : 
    3982    468603878 :     case PLUS_EXPR:
    3983    468603878 :     case MINUS_EXPR:
    3984    468603878 :       {
    3985    468603878 :         tree lhs_etype = lhs_type;
    3986    468603878 :         tree rhs1_etype = rhs1_type;
    3987    468603878 :         tree rhs2_etype = rhs2_type;
    3988    468603878 :         if (VECTOR_TYPE_P (lhs_type))
    3989              :           {
    3990      4706807 :             if (TREE_CODE (rhs1_type) != VECTOR_TYPE
    3991      4706807 :                 || TREE_CODE (rhs2_type) != VECTOR_TYPE)
    3992              :               {
    3993            0 :                 error ("invalid non-vector operands to %qs", code_name);
    3994            0 :                 return true;
    3995              :               }
    3996      4706807 :             lhs_etype = TREE_TYPE (lhs_type);
    3997      4706807 :             rhs1_etype = TREE_TYPE (rhs1_type);
    3998      4706807 :             rhs2_etype = TREE_TYPE (rhs2_type);
    3999              :           }
    4000    468603878 :         if (POINTER_TYPE_P (lhs_etype)
    4001    468603878 :             || POINTER_TYPE_P (rhs1_etype)
    4002    468603878 :             || POINTER_TYPE_P (rhs2_etype))
    4003              :           {
    4004            0 :             error ("invalid (pointer) operands %qs", code_name);
    4005            0 :             return true;
    4006              :           }
    4007              : 
    4008              :         /* Continue with generic binary expression handling.  */
    4009              :         break;
    4010              :       }
    4011              : 
    4012    157977650 :     case POINTER_PLUS_EXPR:
    4013    157977650 :       {
    4014    157977650 :         if (!POINTER_TYPE_P (rhs1_type)
    4015    157977650 :             || !useless_type_conversion_p (lhs_type, rhs1_type)
    4016    315955300 :             || !ptrofftype_p (rhs2_type))
    4017              :           {
    4018            0 :             error ("type mismatch in %qs", code_name);
    4019            0 :             debug_generic_stmt (lhs_type);
    4020            0 :             debug_generic_stmt (rhs1_type);
    4021            0 :             debug_generic_stmt (rhs2_type);
    4022            0 :             return true;
    4023              :           }
    4024              : 
    4025              :         return false;
    4026              :       }
    4027              : 
    4028     16978682 :     case POINTER_DIFF_EXPR:
    4029     16978682 :       {
    4030     16978682 :         if (!POINTER_TYPE_P (rhs1_type)
    4031     16978682 :             || !POINTER_TYPE_P (rhs2_type)
    4032              :             /* Because we special-case pointers to void we allow difference
    4033              :                of arbitrary pointers with the same mode.  */
    4034     16978682 :             || TYPE_MODE (rhs1_type) != TYPE_MODE (rhs2_type)
    4035     16978682 :             || !INTEGRAL_TYPE_P (lhs_type)
    4036     16978682 :             || TYPE_UNSIGNED (lhs_type)
    4037     33957364 :             || TYPE_PRECISION (lhs_type) != TYPE_PRECISION (rhs1_type))
    4038              :           {
    4039            0 :             error ("type mismatch in %qs", code_name);
    4040            0 :             debug_generic_stmt (lhs_type);
    4041            0 :             debug_generic_stmt (rhs1_type);
    4042            0 :             debug_generic_stmt (rhs2_type);
    4043            0 :             return true;
    4044              :           }
    4045              : 
    4046              :         return false;
    4047              :       }
    4048              : 
    4049            0 :     case TRUTH_ANDIF_EXPR:
    4050            0 :     case TRUTH_ORIF_EXPR:
    4051            0 :     case TRUTH_AND_EXPR:
    4052            0 :     case TRUTH_OR_EXPR:
    4053            0 :     case TRUTH_XOR_EXPR:
    4054              : 
    4055            0 :       gcc_unreachable ();
    4056              : 
    4057     90516573 :     case LT_EXPR:
    4058     90516573 :     case LE_EXPR:
    4059     90516573 :     case GT_EXPR:
    4060     90516573 :     case GE_EXPR:
    4061     90516573 :     case EQ_EXPR:
    4062     90516573 :     case NE_EXPR:
    4063     90516573 :     case UNORDERED_EXPR:
    4064     90516573 :     case ORDERED_EXPR:
    4065     90516573 :     case UNLT_EXPR:
    4066     90516573 :     case UNLE_EXPR:
    4067     90516573 :     case UNGT_EXPR:
    4068     90516573 :     case UNGE_EXPR:
    4069     90516573 :     case UNEQ_EXPR:
    4070     90516573 :     case LTGT_EXPR:
    4071              :       /* Comparisons are also binary, but the result type is not
    4072              :          connected to the operand types.  */
    4073     90516573 :       return verify_gimple_comparison (lhs_type, rhs1, rhs2, rhs_code);
    4074              : 
    4075       211223 :     case WIDEN_MULT_EXPR:
    4076       211223 :       if (TREE_CODE (lhs_type) != INTEGER_TYPE)
    4077              :         return true;
    4078       211223 :       return ((2 * TYPE_PRECISION (rhs1_type) > TYPE_PRECISION (lhs_type))
    4079       211223 :               || (TYPE_PRECISION (rhs1_type) != TYPE_PRECISION (rhs2_type)));
    4080              : 
    4081            0 :     case WIDEN_SUM_EXPR:
    4082            0 :       {
    4083            0 :         if (((TREE_CODE (rhs1_type) != VECTOR_TYPE
    4084            0 :               || TREE_CODE (lhs_type) != VECTOR_TYPE)
    4085            0 :              && ((!INTEGRAL_TYPE_P (rhs1_type)
    4086            0 :                   && !SCALAR_FLOAT_TYPE_P (rhs1_type))
    4087            0 :                  || (!INTEGRAL_TYPE_P (lhs_type)
    4088            0 :                      && !SCALAR_FLOAT_TYPE_P (lhs_type))))
    4089            0 :             || !useless_type_conversion_p (lhs_type, rhs2_type)
    4090            0 :             || maybe_lt (GET_MODE_SIZE (element_mode (rhs2_type)),
    4091            0 :                          2 * GET_MODE_SIZE (element_mode (rhs1_type))))
    4092              :           {
    4093            0 :             error ("type mismatch in %qs", code_name);
    4094            0 :             debug_generic_expr (lhs_type);
    4095            0 :             debug_generic_expr (rhs1_type);
    4096            0 :             debug_generic_expr (rhs2_type);
    4097            0 :             return true;
    4098              :           }
    4099              :         return false;
    4100              :       }
    4101              : 
    4102        39809 :     case VEC_WIDEN_MULT_HI_EXPR:
    4103        39809 :     case VEC_WIDEN_MULT_LO_EXPR:
    4104        39809 :     case VEC_WIDEN_MULT_EVEN_EXPR:
    4105        39809 :     case VEC_WIDEN_MULT_ODD_EXPR:
    4106        39809 :       {
    4107        39809 :         if (TREE_CODE (rhs1_type) != VECTOR_TYPE
    4108        39809 :             || TREE_CODE (lhs_type) != VECTOR_TYPE
    4109        39809 :             || !types_compatible_p (rhs1_type, rhs2_type)
    4110       119427 :             || maybe_ne (GET_MODE_SIZE (element_mode (lhs_type)),
    4111        79618 :                          2 * GET_MODE_SIZE (element_mode (rhs1_type))))
    4112              :           {
    4113            0 :             error ("type mismatch in %qs", code_name);
    4114            0 :             debug_generic_expr (lhs_type);
    4115            0 :             debug_generic_expr (rhs1_type);
    4116            0 :             debug_generic_expr (rhs2_type);
    4117            0 :             return true;
    4118              :           }
    4119              :         return false;
    4120              :       }
    4121              : 
    4122       479500 :     case VEC_PACK_TRUNC_EXPR:
    4123              :       /* ???  We currently use VEC_PACK_TRUNC_EXPR to simply concat
    4124              :          vector boolean types.  */
    4125       479500 :       if (VECTOR_BOOLEAN_TYPE_P (lhs_type)
    4126       113254 :           && VECTOR_BOOLEAN_TYPE_P (rhs1_type)
    4127       113254 :           && types_compatible_p (rhs1_type, rhs2_type)
    4128       959000 :           && known_eq (TYPE_VECTOR_SUBPARTS (lhs_type),
    4129              :                        2 * TYPE_VECTOR_SUBPARTS (rhs1_type)))
    4130       113254 :         return false;
    4131              : 
    4132              :       /* Fallthru.  */
    4133       380489 :     case VEC_PACK_SAT_EXPR:
    4134       380489 :     case VEC_PACK_FIX_TRUNC_EXPR:
    4135       380489 :       {
    4136       380489 :         if (TREE_CODE (rhs1_type) != VECTOR_TYPE
    4137       380489 :             || TREE_CODE (lhs_type) != VECTOR_TYPE
    4138       746735 :             || !((rhs_code == VEC_PACK_FIX_TRUNC_EXPR
    4139        14243 :                   && SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs1_type))
    4140        14243 :                   && INTEGRAL_TYPE_P (TREE_TYPE (lhs_type)))
    4141       366246 :                  || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
    4142       366246 :                      == INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))))
    4143       380489 :             || !types_compatible_p (rhs1_type, rhs2_type)
    4144       760978 :             || maybe_ne (GET_MODE_SIZE (element_mode (rhs1_type)),
    4145       760978 :                          2 * GET_MODE_SIZE (element_mode (lhs_type)))
    4146       760978 :             || maybe_ne (2 * TYPE_VECTOR_SUBPARTS (rhs1_type),
    4147       760978 :                          TYPE_VECTOR_SUBPARTS (lhs_type)))
    4148              :           {
    4149            0 :             error ("type mismatch in %qs", code_name);
    4150            0 :             debug_generic_expr (lhs_type);
    4151            0 :             debug_generic_expr (rhs1_type);
    4152            0 :             debug_generic_expr (rhs2_type);
    4153            0 :             return true;
    4154              :           }
    4155              : 
    4156              :         return false;
    4157              :       }
    4158              : 
    4159         1186 :     case VEC_PACK_FLOAT_EXPR:
    4160         1186 :       if (TREE_CODE (rhs1_type) != VECTOR_TYPE
    4161         1186 :           || TREE_CODE (lhs_type) != VECTOR_TYPE
    4162         1186 :           || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
    4163         1186 :           || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (lhs_type))
    4164         1186 :           || !types_compatible_p (rhs1_type, rhs2_type)
    4165         2372 :           || maybe_ne (GET_MODE_SIZE (element_mode (rhs1_type)),
    4166         2372 :                        2 * GET_MODE_SIZE (element_mode (lhs_type)))
    4167         2372 :           || maybe_ne (2 * TYPE_VECTOR_SUBPARTS (rhs1_type),
    4168         2372 :                        TYPE_VECTOR_SUBPARTS (lhs_type)))
    4169              :         {
    4170            0 :           error ("type mismatch in %qs", code_name);
    4171            0 :           debug_generic_expr (lhs_type);
    4172            0 :           debug_generic_expr (rhs1_type);
    4173            0 :           debug_generic_expr (rhs2_type);
    4174            0 :           return true;
    4175              :         }
    4176              : 
    4177              :       return false;
    4178              : 
    4179    216990784 :     case MULT_EXPR:
    4180    216990784 :     case MULT_HIGHPART_EXPR:
    4181    216990784 :     case TRUNC_DIV_EXPR:
    4182    216990784 :     case CEIL_DIV_EXPR:
    4183    216990784 :     case FLOOR_DIV_EXPR:
    4184    216990784 :     case ROUND_DIV_EXPR:
    4185    216990784 :     case TRUNC_MOD_EXPR:
    4186    216990784 :     case CEIL_MOD_EXPR:
    4187    216990784 :     case FLOOR_MOD_EXPR:
    4188    216990784 :     case ROUND_MOD_EXPR:
    4189    216990784 :     case RDIV_EXPR:
    4190    216990784 :     case EXACT_DIV_EXPR:
    4191    216990784 :     case BIT_IOR_EXPR:
    4192    216990784 :     case BIT_XOR_EXPR:
    4193              :       /* Disallow pointer and offset types for many of the binary gimple. */
    4194    216990784 :       if (POINTER_TYPE_P (lhs_type)
    4195    216990784 :           || TREE_CODE (lhs_type) == OFFSET_TYPE)
    4196              :         {
    4197            0 :           error ("invalid types for %qs", code_name);
    4198            0 :           debug_generic_expr (lhs_type);
    4199            0 :           debug_generic_expr (rhs1_type);
    4200            0 :           debug_generic_expr (rhs2_type);
    4201            0 :           return true;
    4202              :         }
    4203              :       /* Continue with generic binary expression handling.  */
    4204              :       break;
    4205              : 
    4206              :     case MIN_EXPR:
    4207              :     case MAX_EXPR:
    4208              :       /* Continue with generic binary expression handling.  */
    4209              :       break;
    4210              : 
    4211     51568511 :     case BIT_AND_EXPR:
    4212     51568511 :       if (POINTER_TYPE_P (lhs_type)
    4213       173931 :           && TREE_CODE (rhs2) == INTEGER_CST)
    4214              :         break;
    4215              :       /* Disallow pointer and offset types for many of the binary gimple. */
    4216     51394580 :       if (POINTER_TYPE_P (lhs_type)
    4217     51394580 :           || TREE_CODE (lhs_type) == OFFSET_TYPE)
    4218              :         {
    4219            0 :           error ("invalid types for %qs", code_name);
    4220            0 :           debug_generic_expr (lhs_type);
    4221            0 :           debug_generic_expr (rhs1_type);
    4222            0 :           debug_generic_expr (rhs2_type);
    4223            0 :           return true;
    4224              :         }
    4225              :       /* Continue with generic binary expression handling.  */
    4226              :       break;
    4227              : 
    4228            0 :     case VEC_SERIES_EXPR:
    4229            0 :       if (!useless_type_conversion_p (rhs1_type, rhs2_type))
    4230              :         {
    4231            0 :           error ("type mismatch in %qs", code_name);
    4232            0 :           debug_generic_expr (rhs1_type);
    4233            0 :           debug_generic_expr (rhs2_type);
    4234            0 :           return true;
    4235              :         }
    4236            0 :       if (TREE_CODE (lhs_type) != VECTOR_TYPE
    4237            0 :           || !useless_type_conversion_p (TREE_TYPE (lhs_type), rhs1_type))
    4238              :         {
    4239            0 :           error ("vector type expected in %qs", code_name);
    4240            0 :           debug_generic_expr (lhs_type);
    4241            0 :           return true;
    4242              :         }
    4243              :       return false;
    4244              : 
    4245            0 :     default:
    4246            0 :       gcc_unreachable ();
    4247              :     }
    4248              : 
    4249    754257595 :   if (!useless_type_conversion_p (lhs_type, rhs1_type)
    4250    754257595 :       || !useless_type_conversion_p (lhs_type, rhs2_type))
    4251              :     {
    4252            0 :       error ("type mismatch in binary expression");
    4253            0 :       debug_generic_stmt (lhs_type);
    4254            0 :       debug_generic_stmt (rhs1_type);
    4255            0 :       debug_generic_stmt (rhs2_type);
    4256            0 :       return true;
    4257              :     }
    4258              : 
    4259              :   return false;
    4260              : }
    4261              : 
    4262              : /* Verify a gimple assignment statement STMT with a ternary rhs.
    4263              :    Returns true if anything is wrong.  */
    4264              : 
    4265              : static bool
    4266      9979868 : verify_gimple_assign_ternary (gassign *stmt)
    4267              : {
    4268      9979868 :   enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
    4269      9979868 :   tree lhs = gimple_assign_lhs (stmt);
    4270      9979868 :   tree lhs_type = TREE_TYPE (lhs);
    4271      9979868 :   tree rhs1 = gimple_assign_rhs1 (stmt);
    4272      9979868 :   tree rhs1_type = TREE_TYPE (rhs1);
    4273      9979868 :   tree rhs2 = gimple_assign_rhs2 (stmt);
    4274      9979868 :   tree rhs2_type = TREE_TYPE (rhs2);
    4275      9979868 :   tree rhs3 = gimple_assign_rhs3 (stmt);
    4276      9979868 :   tree rhs3_type = TREE_TYPE (rhs3);
    4277              : 
    4278      9979868 :   if (!is_gimple_reg (lhs))
    4279              :     {
    4280            0 :       error ("non-register as LHS of ternary operation");
    4281            0 :       return true;
    4282              :     }
    4283              : 
    4284      9979868 :   if (!is_gimple_val (rhs1)
    4285      9979868 :       || !is_gimple_val (rhs2)
    4286     19959736 :       || !is_gimple_val (rhs3))
    4287              :     {
    4288            0 :       error ("invalid operands in ternary operation");
    4289            0 :       return true;
    4290              :     }
    4291              : 
    4292      9979868 :   const char* const code_name = get_tree_code_name (rhs_code);
    4293              : 
    4294              :   /* First handle operations that involve different types.  */
    4295      9979868 :   switch (rhs_code)
    4296              :     {
    4297            0 :     case WIDEN_MULT_PLUS_EXPR:
    4298            0 :     case WIDEN_MULT_MINUS_EXPR:
    4299            0 :       if ((!INTEGRAL_TYPE_P (rhs1_type)
    4300            0 :            && !FIXED_POINT_TYPE_P (rhs1_type))
    4301            0 :           || !useless_type_conversion_p (rhs1_type, rhs2_type)
    4302            0 :           || !useless_type_conversion_p (lhs_type, rhs3_type)
    4303            0 :           || 2 * TYPE_PRECISION (rhs1_type) > TYPE_PRECISION (lhs_type)
    4304            0 :           || TYPE_PRECISION (rhs1_type) != TYPE_PRECISION (rhs2_type))
    4305              :         {
    4306            0 :           error ("type mismatch in %qs", code_name);
    4307            0 :           debug_generic_expr (lhs_type);
    4308            0 :           debug_generic_expr (rhs1_type);
    4309            0 :           debug_generic_expr (rhs2_type);
    4310            0 :           debug_generic_expr (rhs3_type);
    4311            0 :           return true;
    4312              :         }
    4313              :       break;
    4314              : 
    4315      1838238 :     case VEC_COND_EXPR:
    4316      1838238 :       if (!VECTOR_BOOLEAN_TYPE_P (rhs1_type)
    4317      3676476 :           || maybe_ne (TYPE_VECTOR_SUBPARTS (rhs1_type),
    4318      3676476 :                        TYPE_VECTOR_SUBPARTS (lhs_type)))
    4319              :         {
    4320            0 :           error ("the first argument of a %qs must be of a "
    4321              :                  "boolean vector type of the same number of elements "
    4322              :                  "as the result", code_name);
    4323            0 :           debug_generic_expr (lhs_type);
    4324            0 :           debug_generic_expr (rhs1_type);
    4325            0 :           return true;
    4326              :         }
    4327              :       /* Fallthrough.  */
    4328      2954507 :     case COND_EXPR:
    4329      2954507 :       if (!useless_type_conversion_p (lhs_type, rhs2_type)
    4330      2954507 :           || !useless_type_conversion_p (lhs_type, rhs3_type))
    4331              :         {
    4332            0 :           error ("type mismatch in %qs", code_name);
    4333            0 :           debug_generic_expr (lhs_type);
    4334            0 :           debug_generic_expr (rhs2_type);
    4335            0 :           debug_generic_expr (rhs3_type);
    4336            0 :           return true;
    4337              :         }
    4338              :       break;
    4339              : 
    4340      6899106 :     case VEC_PERM_EXPR:
    4341              :       /* If permute is constant, then we allow for lhs and rhs
    4342              :          to have different vector types, provided:
    4343              :          (1) lhs, rhs1, rhs2 have same element type.
    4344              :          (2) rhs3 vector is constant and has integer element type.
    4345              :          (3) len(lhs) == len(rhs3) && len(rhs1) == len(rhs2).  */
    4346              : 
    4347      6899106 :       if (TREE_CODE (lhs_type) != VECTOR_TYPE
    4348      6899106 :           || TREE_CODE (rhs1_type) != VECTOR_TYPE
    4349      6899106 :           || TREE_CODE (rhs2_type) != VECTOR_TYPE
    4350      6899106 :           || TREE_CODE (rhs3_type) != VECTOR_TYPE)
    4351              :         {
    4352            0 :           error ("vector types expected in %qs", code_name);
    4353            0 :           debug_generic_expr (lhs_type);
    4354            0 :           debug_generic_expr (rhs1_type);
    4355            0 :           debug_generic_expr (rhs2_type);
    4356            0 :           debug_generic_expr (rhs3_type);
    4357            0 :           return true;
    4358              :         }
    4359              : 
    4360              :       /* If rhs3 is constant, we allow lhs, rhs1 and rhs2 to be different vector types,
    4361              :          as long as lhs, rhs1 and rhs2 have same element type.  */
    4362      6899106 :       if (TREE_CONSTANT (rhs3)
    4363      6899106 :           ? (!useless_type_conversion_p (TREE_TYPE (lhs_type), TREE_TYPE (rhs1_type))
    4364      6779307 :              || !useless_type_conversion_p (TREE_TYPE (lhs_type), TREE_TYPE (rhs2_type)))
    4365       119799 :           : (!useless_type_conversion_p (lhs_type, rhs1_type)
    4366       119799 :              || !useless_type_conversion_p (lhs_type, rhs2_type)))
    4367              :         {
    4368            0 :             error ("type mismatch in %qs", code_name);
    4369            0 :             debug_generic_expr (lhs_type);
    4370            0 :             debug_generic_expr (rhs1_type);
    4371            0 :             debug_generic_expr (rhs2_type);
    4372            0 :             debug_generic_expr (rhs3_type);
    4373            0 :             return true;
    4374              :         }
    4375              : 
    4376              :       /* If rhs3 is constant, relax the check len(rhs2) == len(rhs3).  */
    4377      6899106 :       if (maybe_ne (TYPE_VECTOR_SUBPARTS (rhs1_type),
    4378      6899106 :                     TYPE_VECTOR_SUBPARTS (rhs2_type))
    4379      6899106 :           || (!TREE_CONSTANT(rhs3)
    4380       119799 :               && maybe_ne (TYPE_VECTOR_SUBPARTS (rhs2_type),
    4381       119799 :                            TYPE_VECTOR_SUBPARTS (rhs3_type)))
    4382     13798212 :           || maybe_ne (TYPE_VECTOR_SUBPARTS (rhs3_type),
    4383      6899106 :                        TYPE_VECTOR_SUBPARTS (lhs_type)))
    4384              :         {
    4385            0 :           error ("vectors with different element number found in %qs",
    4386              :                  code_name);
    4387            0 :           debug_generic_expr (lhs_type);
    4388            0 :           debug_generic_expr (rhs1_type);
    4389            0 :           debug_generic_expr (rhs2_type);
    4390            0 :           debug_generic_expr (rhs3_type);
    4391            0 :           return true;
    4392              :         }
    4393              : 
    4394      6899106 :       if (TREE_CODE (TREE_TYPE (rhs3_type)) != INTEGER_TYPE
    4395      6899106 :           || (TREE_CODE (rhs3) != VECTOR_CST
    4396       119799 :               && (GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE
    4397              :                                     (TREE_TYPE (rhs3_type)))
    4398      7018905 :                   != GET_MODE_BITSIZE (SCALAR_TYPE_MODE
    4399              :                                        (TREE_TYPE (rhs1_type))))))
    4400              :         {
    4401            0 :           error ("invalid mask type in %qs", code_name);
    4402            0 :           debug_generic_expr (lhs_type);
    4403            0 :           debug_generic_expr (rhs1_type);
    4404            0 :           debug_generic_expr (rhs2_type);
    4405            0 :           debug_generic_expr (rhs3_type);
    4406            0 :           return true;
    4407              :         }
    4408              : 
    4409              :       return false;
    4410              : 
    4411         4558 :     case SAD_EXPR:
    4412         4558 :       if (!useless_type_conversion_p (rhs1_type, rhs2_type)
    4413         4558 :           || !useless_type_conversion_p (lhs_type, rhs3_type)
    4414         9116 :           || 2 * GET_MODE_UNIT_BITSIZE (TYPE_MODE (TREE_TYPE (rhs1_type)))
    4415         9116 :                > GET_MODE_UNIT_BITSIZE (TYPE_MODE (TREE_TYPE (lhs_type))))
    4416              :         {
    4417            0 :           error ("type mismatch in %qs", code_name);
    4418            0 :           debug_generic_expr (lhs_type);
    4419            0 :           debug_generic_expr (rhs1_type);
    4420            0 :           debug_generic_expr (rhs2_type);
    4421            0 :           debug_generic_expr (rhs3_type);
    4422            0 :           return true;
    4423              :         }
    4424              : 
    4425         4558 :       if (TREE_CODE (rhs1_type) != VECTOR_TYPE
    4426         4558 :           || TREE_CODE (rhs2_type) != VECTOR_TYPE
    4427         4558 :           || TREE_CODE (rhs3_type) != VECTOR_TYPE)
    4428              :         {
    4429            0 :           error ("vector types expected in %qs", code_name);
    4430            0 :           debug_generic_expr (lhs_type);
    4431            0 :           debug_generic_expr (rhs1_type);
    4432            0 :           debug_generic_expr (rhs2_type);
    4433            0 :           debug_generic_expr (rhs3_type);
    4434            0 :           return true;
    4435              :         }
    4436              : 
    4437              :       return false;
    4438              : 
    4439       104525 :     case BIT_INSERT_EXPR:
    4440       104525 :       if (! useless_type_conversion_p (lhs_type, rhs1_type))
    4441              :         {
    4442            0 :           error ("type mismatch in %qs", code_name);
    4443            0 :           debug_generic_expr (lhs_type);
    4444            0 :           debug_generic_expr (rhs1_type);
    4445            0 :           return true;
    4446              :         }
    4447       104525 :       if (! ((INTEGRAL_TYPE_P (rhs1_type)
    4448         5472 :               && INTEGRAL_TYPE_P (rhs2_type))
    4449              :              /* Vector element insert.  */
    4450        99053 :              || (VECTOR_TYPE_P (rhs1_type)
    4451        99053 :                  && types_compatible_p (TREE_TYPE (rhs1_type), rhs2_type))
    4452              :              /* Aligned sub-vector insert.  */
    4453         4292 :              || (VECTOR_TYPE_P (rhs1_type)
    4454         4292 :                  && VECTOR_TYPE_P (rhs2_type)
    4455         4292 :                  && types_compatible_p (TREE_TYPE (rhs1_type),
    4456         4292 :                                         TREE_TYPE (rhs2_type))
    4457         4292 :                  && multiple_p (TYPE_VECTOR_SUBPARTS (rhs1_type),
    4458         4292 :                                 TYPE_VECTOR_SUBPARTS (rhs2_type))
    4459         4292 :                  && multiple_p (wi::to_poly_offset (rhs3),
    4460         4292 :                                 wi::to_poly_offset (TYPE_SIZE (rhs2_type))))))
    4461              :         {
    4462            0 :           error ("not allowed type combination in %qs", code_name);
    4463            0 :           debug_generic_expr (rhs1_type);
    4464            0 :           debug_generic_expr (rhs2_type);
    4465            0 :           return true;
    4466              :         }
    4467       104525 :       if (! tree_fits_uhwi_p (rhs3)
    4468       104525 :           || ! types_compatible_p (bitsizetype, TREE_TYPE (rhs3))
    4469       209050 :           || ! tree_fits_uhwi_p (TYPE_SIZE (rhs2_type)))
    4470              :         {
    4471            0 :           error ("invalid position or size in %qs", code_name);
    4472            0 :           return true;
    4473              :         }
    4474       104525 :       if (INTEGRAL_TYPE_P (rhs1_type)
    4475       104525 :           && !type_has_mode_precision_p (rhs1_type))
    4476              :         {
    4477            0 :           error ("%qs into non-mode-precision operand", code_name);
    4478            0 :           return true;
    4479              :         }
    4480       104525 :       if (INTEGRAL_TYPE_P (rhs1_type))
    4481              :         {
    4482         5472 :           unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (rhs3);
    4483         5472 :           if (bitpos >= TYPE_PRECISION (rhs1_type)
    4484         5472 :               || (bitpos + TYPE_PRECISION (rhs2_type)
    4485         5472 :                   > TYPE_PRECISION (rhs1_type)))
    4486              :             {
    4487            0 :               error ("insertion out of range in %qs", code_name);
    4488            0 :               return true;
    4489              :             }
    4490              :         }
    4491        99053 :       else if (VECTOR_TYPE_P (rhs1_type))
    4492              :         {
    4493        99053 :           unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (rhs3);
    4494        99053 :           unsigned HOST_WIDE_INT bitsize = tree_to_uhwi (TYPE_SIZE (rhs2_type));
    4495        99053 :           if (bitpos % bitsize != 0)
    4496              :             {
    4497            0 :               error ("%qs not at element boundary", code_name);
    4498            0 :               return true;
    4499              :             }
    4500              :         }
    4501              :       return false;
    4502              : 
    4503        17172 :     case DOT_PROD_EXPR:
    4504        17172 :       {
    4505        17172 :         if (((TREE_CODE (rhs1_type) != VECTOR_TYPE
    4506        17172 :               || TREE_CODE (lhs_type) != VECTOR_TYPE)
    4507            0 :              && ((!INTEGRAL_TYPE_P (rhs1_type)
    4508            0 :                   && !SCALAR_FLOAT_TYPE_P (rhs1_type))
    4509            0 :                  || (!INTEGRAL_TYPE_P (lhs_type)
    4510            0 :                      && !SCALAR_FLOAT_TYPE_P (lhs_type))))
    4511              :             /* rhs1_type and rhs2_type may differ in sign.  */
    4512        17172 :             || !tree_nop_conversion_p (rhs1_type, rhs2_type)
    4513        17172 :             || !useless_type_conversion_p (lhs_type, rhs3_type)
    4514        51516 :             || maybe_lt (GET_MODE_SIZE (element_mode (rhs3_type)),
    4515        34344 :                          2 * GET_MODE_SIZE (element_mode (rhs1_type))))
    4516              :           {
    4517            0 :             error ("type mismatch in %qs", code_name);
    4518            0 :             debug_generic_expr (lhs_type);
    4519            0 :             debug_generic_expr (rhs1_type);
    4520            0 :             debug_generic_expr (rhs2_type);
    4521            0 :             return true;
    4522              :           }
    4523              :         return false;
    4524              :       }
    4525              : 
    4526              :     case REALIGN_LOAD_EXPR:
    4527              :       /* FIXME.  */
    4528              :       return false;
    4529              : 
    4530            0 :     default:
    4531            0 :       gcc_unreachable ();
    4532              :     }
    4533              :   return false;
    4534              : }
    4535              : 
    4536              : /* Verify a gimple assignment statement STMT with a single rhs.
    4537              :    Returns true if anything is wrong.  */
    4538              : 
    4539              : static bool
    4540   3182948259 : verify_gimple_assign_single (gassign *stmt)
    4541              : {
    4542   3182948259 :   enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
    4543   3182948259 :   tree lhs = gimple_assign_lhs (stmt);
    4544   3182948259 :   tree lhs_type = TREE_TYPE (lhs);
    4545   3182948259 :   tree rhs1 = gimple_assign_rhs1 (stmt);
    4546   3182948259 :   tree rhs1_type = TREE_TYPE (rhs1);
    4547   3182948259 :   bool res = false;
    4548              : 
    4549   3182948259 :   const char* const code_name = get_tree_code_name (rhs_code);
    4550              : 
    4551   3182948259 :   if (!useless_type_conversion_p (lhs_type, rhs1_type))
    4552              :     {
    4553            0 :       error ("non-trivial conversion in %qs", code_name);
    4554            0 :       debug_generic_expr (lhs_type);
    4555            0 :       debug_generic_expr (rhs1_type);
    4556            0 :       return true;
    4557              :     }
    4558              : 
    4559              :   /* LHS can't be a constant or an address expression. */
    4560   3182948259 :   if (CONSTANT_CLASS_P (lhs)|| TREE_CODE (lhs) == ADDR_EXPR)
    4561              :     {
    4562            0 :       error ("invalid LHS (%qs) for assignment: %qs",
    4563              :              get_tree_code_name (TREE_CODE (lhs)), code_name);
    4564            0 :       return true;
    4565              :     }
    4566              : 
    4567   3182948259 :   if (gimple_clobber_p (stmt)
    4568   3182948259 :       && !(DECL_P (lhs) || TREE_CODE (lhs) == MEM_REF))
    4569              :     {
    4570            0 :       error ("%qs LHS in clobber statement",
    4571              :              get_tree_code_name (TREE_CODE (lhs)));
    4572            0 :       debug_generic_expr (lhs);
    4573            0 :       return true;
    4574              :     }
    4575              : 
    4576   3182948259 :   if (TREE_CODE (lhs) == WITH_SIZE_EXPR)
    4577              :     {
    4578            0 :       error ("%qs LHS in assignment statement",
    4579              :              get_tree_code_name (TREE_CODE (lhs)));
    4580            0 :       debug_generic_expr (lhs);
    4581            0 :       return true;
    4582              :     }
    4583              : 
    4584   3182948259 :   if (handled_component_p (lhs)
    4585   2361786802 :       || TREE_CODE (lhs) == MEM_REF
    4586   2107950250 :       || TREE_CODE (lhs) == TARGET_MEM_REF)
    4587   1084097817 :     res |= verify_types_in_gimple_reference (lhs, true);
    4588              : 
    4589              :   /* Special codes we cannot handle via their class.  */
    4590   3182948259 :   switch (rhs_code)
    4591              :     {
    4592    267985868 :     case ADDR_EXPR:
    4593    267985868 :       {
    4594    267985868 :         tree op = TREE_OPERAND (rhs1, 0);
    4595    267985868 :         if (!is_gimple_addressable (op))
    4596              :           {
    4597            0 :             error ("invalid operand in %qs", code_name);
    4598            0 :             return true;
    4599              :           }
    4600              : 
    4601              :         /* Technically there is no longer a need for matching types, but
    4602              :            gimple hygiene asks for this check.  In LTO we can end up
    4603              :            combining incompatible units and thus end up with addresses
    4604              :            of globals that change their type to a common one.  */
    4605    267985868 :         if (!in_lto_p
    4606    267475713 :             && !types_compatible_p (TREE_TYPE (op),
    4607    267475713 :                                     TREE_TYPE (TREE_TYPE (rhs1)))
    4608    267986048 :             && !one_pointer_to_useless_type_conversion_p (TREE_TYPE (rhs1),
    4609          180 :                                                           TREE_TYPE (op)))
    4610              :           {
    4611            0 :             error ("type mismatch in %qs", code_name);
    4612            0 :             debug_generic_stmt (TREE_TYPE (rhs1));
    4613            0 :             debug_generic_stmt (TREE_TYPE (op));
    4614            0 :             return true;
    4615              :           }
    4616              : 
    4617    267985868 :         return (verify_address (rhs1, true)
    4618    267985868 :                 || verify_types_in_gimple_reference (op, true));
    4619              :       }
    4620              : 
    4621              :     /* tcc_reference  */
    4622            0 :     case INDIRECT_REF:
    4623            0 :       error ("%qs in gimple IL", code_name);
    4624            0 :       return true;
    4625              : 
    4626           46 :     case WITH_SIZE_EXPR:
    4627           46 :       if (!is_gimple_val (TREE_OPERAND (rhs1, 1)))
    4628              :         {
    4629            0 :           error ("invalid %qs size argument in load", code_name);
    4630            0 :           debug_generic_stmt (lhs);
    4631            0 :           debug_generic_stmt (rhs1);
    4632            0 :           return true;
    4633              :         }
    4634           46 :       rhs1 = TREE_OPERAND (rhs1, 0);
    4635              :       /* Fallthru.  */
    4636   1090686378 :     case COMPONENT_REF:
    4637   1090686378 :     case BIT_FIELD_REF:
    4638   1090686378 :     case ARRAY_REF:
    4639   1090686378 :     case ARRAY_RANGE_REF:
    4640   1090686378 :     case VIEW_CONVERT_EXPR:
    4641   1090686378 :     case REALPART_EXPR:
    4642   1090686378 :     case IMAGPART_EXPR:
    4643   1090686378 :     case TARGET_MEM_REF:
    4644   1090686378 :     case MEM_REF:
    4645   1090686378 :       if (!is_gimple_reg (lhs)
    4646   1090686378 :           && is_gimple_reg_type (TREE_TYPE (lhs)))
    4647              :         {
    4648            0 :           error ("invalid RHS for gimple memory store: %qs", code_name);
    4649            0 :           debug_generic_stmt (lhs);
    4650            0 :           debug_generic_stmt (rhs1);
    4651            0 :           return true;
    4652              :         }
    4653   1090686378 :       return res || verify_types_in_gimple_reference (rhs1, false);
    4654              : 
    4655              :     /* tcc_constant  */
    4656              :     case SSA_NAME:
    4657              :     case INTEGER_CST:
    4658              :     case REAL_CST:
    4659              :     case FIXED_CST:
    4660              :     case COMPLEX_CST:
    4661              :     case VECTOR_CST:
    4662              :     case STRING_CST:
    4663              :       return res;
    4664              : 
    4665              :     /* tcc_declaration  */
    4666              :     case CONST_DECL:
    4667              :       return res;
    4668    328708477 :     case VAR_DECL:
    4669    328708477 :     case PARM_DECL:
    4670    328708477 :       if (!is_gimple_reg (lhs)
    4671     90354268 :           && !is_gimple_reg (rhs1)
    4672    407007604 :           && is_gimple_reg_type (TREE_TYPE (lhs)))
    4673              :         {
    4674            0 :           error ("invalid RHS for gimple memory store: %qs", code_name);
    4675            0 :           debug_generic_stmt (lhs);
    4676            0 :           debug_generic_stmt (rhs1);
    4677            0 :           return true;
    4678              :         }
    4679              :       return res;
    4680              : 
    4681    329857864 :     case CONSTRUCTOR:
    4682    329857864 :       if (VECTOR_TYPE_P (rhs1_type))
    4683              :         {
    4684      6787302 :           unsigned int i;
    4685      6787302 :           tree elt_i, elt_v, elt_t = NULL_TREE;
    4686              : 
    4687      6787302 :           if (CONSTRUCTOR_NELTS (rhs1) == 0)
    4688              :             return res;
    4689      6153437 :           if (!is_gimple_reg (lhs))
    4690              :             {
    4691            0 :               error ("non-register as LHS with vector constructor");
    4692            0 :               return true;
    4693              :             }
    4694              :           /* For vector CONSTRUCTORs we require that either it is empty
    4695              :              CONSTRUCTOR, or it is a CONSTRUCTOR of smaller vector elements
    4696              :              (then the element count must be correct to cover the whole
    4697              :              outer vector and index must be NULL on all elements, or it is
    4698              :              a CONSTRUCTOR of scalar elements, where we as an exception allow
    4699              :              smaller number of elements (assuming zero filling) and
    4700              :              consecutive indexes as compared to NULL indexes (such
    4701              :              CONSTRUCTORs can appear in the IL from FEs).  */
    4702     28450779 :           FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (rhs1), i, elt_i, elt_v)
    4703              :             {
    4704     22297342 :               if (elt_t == NULL_TREE)
    4705              :                 {
    4706      6153437 :                   elt_t = TREE_TYPE (elt_v);
    4707      6153437 :                   if (VECTOR_TYPE_P (elt_t))
    4708              :                     {
    4709       203471 :                       tree elt_t = TREE_TYPE (elt_v);
    4710       203471 :                       if (!useless_type_conversion_p (TREE_TYPE (rhs1_type),
    4711       203471 :                                                       TREE_TYPE (elt_t)))
    4712              :                         {
    4713            0 :                           error ("incorrect type of vector %qs elements",
    4714              :                                  code_name);
    4715            0 :                           debug_generic_stmt (rhs1);
    4716            0 :                           return true;
    4717              :                         }
    4718       406942 :                       else if (maybe_ne (CONSTRUCTOR_NELTS (rhs1)
    4719       406942 :                                          * TYPE_VECTOR_SUBPARTS (elt_t),
    4720       406942 :                                          TYPE_VECTOR_SUBPARTS (rhs1_type)))
    4721              :                         {
    4722            0 :                           error ("incorrect number of vector %qs elements",
    4723              :                                  code_name);
    4724            0 :                           debug_generic_stmt (rhs1);
    4725            0 :                           return true;
    4726              :                         }
    4727              :                     }
    4728      5949966 :                   else if (!useless_type_conversion_p (TREE_TYPE (rhs1_type),
    4729              :                                                        elt_t))
    4730              :                     {
    4731            0 :                       error ("incorrect type of vector %qs elements",
    4732              :                              code_name);
    4733            0 :                       debug_generic_stmt (rhs1);
    4734            0 :                       return true;
    4735              :                     }
    4736     11899932 :                   else if (maybe_gt (CONSTRUCTOR_NELTS (rhs1),
    4737              :                                      TYPE_VECTOR_SUBPARTS (rhs1_type)))
    4738              :                     {
    4739            0 :                       error ("incorrect number of vector %qs elements",
    4740              :                              code_name);
    4741            0 :                       debug_generic_stmt (rhs1);
    4742            0 :                       return true;
    4743              :                     }
    4744              :                 }
    4745     16143905 :               else if (!useless_type_conversion_p (elt_t, TREE_TYPE (elt_v)))
    4746              :                 {
    4747            0 :                   error ("incorrect type of vector CONSTRUCTOR elements");
    4748            0 :                   debug_generic_stmt (rhs1);
    4749            0 :                   return true;
    4750              :                 }
    4751     22297342 :               if (elt_i != NULL_TREE
    4752     22297342 :                   && (VECTOR_TYPE_P (elt_t)
    4753      7779197 :                       || TREE_CODE (elt_i) != INTEGER_CST
    4754      7779197 :                       || compare_tree_int (elt_i, i) != 0))
    4755              :                 {
    4756            0 :                   error ("vector %qs with non-NULL element index",
    4757              :                          code_name);
    4758            0 :                   debug_generic_stmt (rhs1);
    4759            0 :                   return true;
    4760              :                 }
    4761     22297342 :               if (!is_gimple_val (elt_v))
    4762              :                 {
    4763            0 :                   error ("vector %qs element is not a GIMPLE value",
    4764              :                          code_name);
    4765            0 :                   debug_generic_stmt (rhs1);
    4766            0 :                   return true;
    4767              :                 }
    4768              :             }
    4769              :         }
    4770    323070562 :       else if (CONSTRUCTOR_NELTS (rhs1) != 0)
    4771              :         {
    4772            0 :           error ("non-vector %qs with elements", code_name);
    4773            0 :           debug_generic_stmt (rhs1);
    4774            0 :           return true;
    4775              :         }
    4776              :       return res;
    4777              : 
    4778              :     case OBJ_TYPE_REF:
    4779              :       /* FIXME.  */
    4780              :       return res;
    4781              : 
    4782              :     default:;
    4783              :     }
    4784              : 
    4785              :   return res;
    4786              : }
    4787              : 
    4788              : /* Verify the contents of a GIMPLE_ASSIGN STMT.  Returns true when there
    4789              :    is a problem, otherwise false.  */
    4790              : 
    4791              : static bool
    4792   4674234712 : verify_gimple_assign (gassign *stmt)
    4793              : {
    4794   4674234712 :   if (gimple_assign_nontemporal_move_p (stmt))
    4795              :     {
    4796          595 :       tree lhs = gimple_assign_lhs (stmt);
    4797          595 :       if (is_gimple_reg (lhs))
    4798              :         {
    4799            0 :           error ("nontemporal store lhs cannot be a gimple register");
    4800            0 :           debug_generic_stmt (lhs);
    4801            0 :           return true;
    4802              :         }
    4803              :     }
    4804              : 
    4805   4674234712 :   switch (gimple_assign_rhs_class (stmt))
    4806              :     {
    4807   3182948259 :     case GIMPLE_SINGLE_RHS:
    4808   3182948259 :       return verify_gimple_assign_single (stmt);
    4809              : 
    4810    424692850 :     case GIMPLE_UNARY_RHS:
    4811    424692850 :       return verify_gimple_assign_unary (stmt);
    4812              : 
    4813   1056613735 :     case GIMPLE_BINARY_RHS:
    4814   1056613735 :       return verify_gimple_assign_binary (stmt);
    4815              : 
    4816      9979868 :     case GIMPLE_TERNARY_RHS:
    4817      9979868 :       return verify_gimple_assign_ternary (stmt);
    4818              : 
    4819            0 :     default:
    4820            0 :       gcc_unreachable ();
    4821              :     }
    4822              : }
    4823              : 
    4824              : /* Verify the contents of a GIMPLE_RETURN STMT.  Returns true when there
    4825              :    is a problem, otherwise false.  */
    4826              : 
    4827              : static bool
    4828    264419515 : verify_gimple_return (greturn *stmt)
    4829              : {
    4830    264419515 :   tree op = gimple_return_retval (stmt);
    4831    264419515 :   tree restype = TREE_TYPE (TREE_TYPE (cfun->decl));
    4832    264419515 :   tree resdecl = DECL_RESULT (cfun->decl);
    4833              : 
    4834              :   /* We cannot test for present return values as we do not fix up missing
    4835              :      return values from the original source.  */
    4836    264419515 :   if (op == NULL)
    4837              :     return false;
    4838              : 
    4839    147740534 :   if (!is_gimple_val (op)
    4840    147740534 :       && TREE_CODE (op) != RESULT_DECL)
    4841              :     {
    4842            0 :       error ("invalid operand in return statement");
    4843            0 :       debug_generic_stmt (op);
    4844            0 :       return true;
    4845              :     }
    4846              : 
    4847    147740534 :   if (resdecl && DECL_BY_REFERENCE (resdecl))
    4848      3376808 :     op = TREE_TYPE (op);
    4849              : 
    4850    147740534 :   if (!useless_type_conversion_p (restype, TREE_TYPE (op)))
    4851              :     {
    4852            0 :       error ("invalid conversion in return statement");
    4853            0 :       debug_generic_stmt (restype);
    4854            0 :       debug_generic_stmt (TREE_TYPE (op));
    4855            0 :       return true;
    4856              :     }
    4857              : 
    4858              :   return false;
    4859              : }
    4860              : 
    4861              : 
    4862              : /* Verify the contents of a GIMPLE_GOTO STMT.  Returns true when there
    4863              :    is a problem, otherwise false.  */
    4864              : 
    4865              : static bool
    4866     26236806 : verify_gimple_goto (ggoto *stmt)
    4867              : {
    4868     26236806 :   tree dest = gimple_goto_dest (stmt);
    4869              : 
    4870              :   /* ???  We have two canonical forms of direct goto destinations, a
    4871              :      bare LABEL_DECL and an ADDR_EXPR of a LABEL_DECL.  */
    4872     26236806 :   if (TREE_CODE (dest) != LABEL_DECL
    4873     26236806 :       && (!is_gimple_val (dest)
    4874        60258 :           || !POINTER_TYPE_P (TREE_TYPE (dest))))
    4875              :     {
    4876            0 :       error ("goto destination is neither a label nor a pointer");
    4877            0 :       return true;
    4878              :     }
    4879              : 
    4880              :   return false;
    4881              : }
    4882              : 
    4883              : /* Verify the contents of a GIMPLE_SWITCH STMT.  Returns true when there
    4884              :    is a problem, otherwise false.  */
    4885              : 
    4886              : static bool
    4887      4680511 : verify_gimple_switch (gswitch *stmt)
    4888              : {
    4889      4680511 :   unsigned int i, n;
    4890      4680511 :   tree elt, prev_upper_bound = NULL_TREE;
    4891      4680511 :   tree index_type, elt_type = NULL_TREE;
    4892              : 
    4893      4680511 :   if (!is_gimple_val (gimple_switch_index (stmt)))
    4894              :     {
    4895            0 :       error ("invalid operand to switch statement");
    4896            0 :       debug_generic_stmt (gimple_switch_index (stmt));
    4897            0 :       return true;
    4898              :     }
    4899              : 
    4900      4680511 :   index_type = TREE_TYPE (gimple_switch_index (stmt));
    4901      4680511 :   if (! INTEGRAL_TYPE_P (index_type))
    4902              :     {
    4903            0 :       error ("non-integral type switch statement");
    4904            0 :       debug_generic_expr (index_type);
    4905            0 :       return true;
    4906              :     }
    4907              : 
    4908      4680511 :   elt = gimple_switch_label (stmt, 0);
    4909      4680511 :   if (CASE_LOW (elt) != NULL_TREE
    4910      4680511 :       || CASE_HIGH (elt) != NULL_TREE
    4911      9361022 :       || CASE_CHAIN (elt) != NULL_TREE)
    4912              :     {
    4913            0 :       error ("invalid default case label in switch statement");
    4914            0 :       debug_generic_expr (elt);
    4915            0 :       return true;
    4916              :     }
    4917              : 
    4918      4680511 :   n = gimple_switch_num_labels (stmt);
    4919     40546815 :   for (i = 1; i < n; i++)
    4920              :     {
    4921     31185793 :       elt = gimple_switch_label (stmt, i);
    4922              : 
    4923     31185793 :       if (CASE_CHAIN (elt))
    4924              :         {
    4925            0 :           error ("invalid %<CASE_CHAIN%>");
    4926            0 :           debug_generic_expr (elt);
    4927            0 :           return true;
    4928              :         }
    4929     31185793 :       if (! CASE_LOW (elt))
    4930              :         {
    4931            0 :           error ("invalid case label in switch statement");
    4932            0 :           debug_generic_expr (elt);
    4933            0 :           return true;
    4934              :         }
    4935     31185793 :       if (CASE_HIGH (elt)
    4936     31185793 :           && ! tree_int_cst_lt (CASE_LOW (elt), CASE_HIGH (elt)))
    4937              :         {
    4938            0 :           error ("invalid case range in switch statement");
    4939            0 :           debug_generic_expr (elt);
    4940            0 :           return true;
    4941              :         }
    4942              : 
    4943     31185793 :       if (! elt_type)
    4944              :         {
    4945      4677370 :           elt_type = TREE_TYPE (CASE_LOW (elt));
    4946      4677370 :           if (TYPE_PRECISION (index_type) < TYPE_PRECISION (elt_type))
    4947              :             {
    4948            0 :               error ("type precision mismatch in switch statement");
    4949            0 :               return true;
    4950              :             }
    4951              :         }
    4952     31185793 :       if (TREE_TYPE (CASE_LOW (elt)) != elt_type
    4953     31185793 :           || (CASE_HIGH (elt) && TREE_TYPE (CASE_HIGH (elt)) != elt_type))
    4954              :         {
    4955            0 :           error ("type mismatch for case label in switch statement");
    4956            0 :           debug_generic_expr (elt);
    4957            0 :           return true;
    4958              :         }
    4959              : 
    4960     31185793 :       if (prev_upper_bound)
    4961              :         {
    4962     26508423 :           if (! tree_int_cst_lt (prev_upper_bound, CASE_LOW (elt)))
    4963              :             {
    4964            0 :               error ("case labels not sorted in switch statement");
    4965            0 :               return true;
    4966              :             }
    4967              :         }
    4968              : 
    4969     31185793 :       prev_upper_bound = CASE_HIGH (elt);
    4970     31185793 :       if (! prev_upper_bound)
    4971     29230515 :         prev_upper_bound = CASE_LOW (elt);
    4972              :     }
    4973              : 
    4974              :   return false;
    4975              : }
    4976              : 
    4977              : /* Verify a gimple debug statement STMT.
    4978              :    Returns true if anything is wrong.  */
    4979              : 
    4980              : static bool
    4981            0 : verify_gimple_debug (gimple *stmt ATTRIBUTE_UNUSED)
    4982              : {
    4983              :   /* There isn't much that could be wrong in a gimple debug stmt.  A
    4984              :      gimple debug bind stmt, for example, maps a tree, that's usually
    4985              :      a VAR_DECL or a PARM_DECL, but that could also be some scalarized
    4986              :      component or member of an aggregate type, to another tree, that
    4987              :      can be an arbitrary expression.  These stmts expand into debug
    4988              :      insns, and are converted to debug notes by var-tracking.cc.  */
    4989            0 :   return false;
    4990              : }
    4991              : 
    4992              : /* Verify a gimple label statement STMT.
    4993              :    Returns true if anything is wrong.  */
    4994              : 
    4995              : static bool
    4996    229968039 : verify_gimple_label (glabel *stmt)
    4997              : {
    4998    229968039 :   tree decl = gimple_label_label (stmt);
    4999    229968039 :   int uid;
    5000    229968039 :   bool err = false;
    5001              : 
    5002    229968039 :   if (TREE_CODE (decl) != LABEL_DECL)
    5003              :     return true;
    5004    459879082 :   if (!DECL_NONLOCAL (decl) && !FORCED_LABEL (decl)
    5005    456554481 :       && DECL_CONTEXT (decl) != current_function_decl)
    5006              :     {
    5007            0 :       error ("label context is not the current function declaration");
    5008            0 :       err |= true;
    5009              :     }
    5010              : 
    5011    229968039 :   uid = LABEL_DECL_UID (decl);
    5012    229968039 :   if (cfun->cfg
    5013    229968039 :       && (uid == -1
    5014    142186610 :           || (*label_to_block_map_for_fn (cfun))[uid] != gimple_bb (stmt)))
    5015              :     {
    5016            0 :       error ("incorrect entry in %<label_to_block_map%>");
    5017            0 :       err |= true;
    5018              :     }
    5019              : 
    5020    229968039 :   uid = EH_LANDING_PAD_NR (decl);
    5021    229968039 :   if (uid)
    5022              :     {
    5023     79313294 :       eh_landing_pad lp = get_eh_landing_pad_from_number (uid);
    5024     79313294 :       if (decl != lp->post_landing_pad)
    5025              :         {
    5026            0 :           error ("incorrect setting of landing pad number");
    5027            0 :           err |= true;
    5028              :         }
    5029              :     }
    5030              : 
    5031              :   return err;
    5032              : }
    5033              : 
    5034              : /* Verify a gimple cond statement STMT.
    5035              :    Returns true if anything is wrong.  */
    5036              : 
    5037              : static bool
    5038    771883124 : verify_gimple_cond (gcond *stmt)
    5039              : {
    5040    771883124 :   if (TREE_CODE_CLASS (gimple_cond_code (stmt)) != tcc_comparison)
    5041              :     {
    5042            0 :       error ("invalid comparison code in gimple cond");
    5043            0 :       return true;
    5044              :     }
    5045    771883124 :   if (!(!gimple_cond_true_label (stmt)
    5046     29588149 :         || TREE_CODE (gimple_cond_true_label (stmt)) == LABEL_DECL)
    5047    801471273 :       || !(!gimple_cond_false_label (stmt)
    5048     29588149 :            || TREE_CODE (gimple_cond_false_label (stmt)) == LABEL_DECL))
    5049              :     {
    5050            0 :       error ("invalid labels in gimple cond");
    5051            0 :       return true;
    5052              :     }
    5053              : 
    5054    771883124 :   tree lhs = gimple_cond_lhs (stmt);
    5055              : 
    5056              :   /* GIMPLE_CONDs condition may not throw.  */
    5057    771883124 :   if (flag_exceptions
    5058    445184256 :       && cfun->can_throw_non_call_exceptions
    5059   1086392454 :       && operation_could_trap_p (gimple_cond_code (stmt),
    5060    314509330 :                                  FLOAT_TYPE_P (TREE_TYPE (lhs)),
    5061              :                                  false, NULL_TREE))
    5062              :     {
    5063            0 :       error ("gimple cond condition cannot throw");
    5064            0 :       return true;
    5065              :     }
    5066              : 
    5067    771883124 :   return verify_gimple_comparison (boolean_type_node,
    5068              :                                    gimple_cond_lhs (stmt),
    5069              :                                    gimple_cond_rhs (stmt),
    5070    771883124 :                                    gimple_cond_code (stmt));
    5071              : }
    5072              : 
    5073              : /* Verify the GIMPLE statement STMT.  Returns true if there is an
    5074              :    error, otherwise false.  */
    5075              : 
    5076              : static bool
    5077  14003309822 : verify_gimple_stmt (gimple *stmt)
    5078              : {
    5079  14003309822 :   switch (gimple_code (stmt))
    5080              :     {
    5081   4674234712 :     case GIMPLE_ASSIGN:
    5082   4674234712 :       return verify_gimple_assign (as_a <gassign *> (stmt));
    5083              : 
    5084    229968039 :     case GIMPLE_LABEL:
    5085    229968039 :       return verify_gimple_label (as_a <glabel *> (stmt));
    5086              : 
    5087   1096846793 :     case GIMPLE_CALL:
    5088   1096846793 :       return verify_gimple_call (as_a <gcall *> (stmt));
    5089              : 
    5090    771883124 :     case GIMPLE_COND:
    5091    771883124 :       return verify_gimple_cond (as_a <gcond *> (stmt));
    5092              : 
    5093     26236806 :     case GIMPLE_GOTO:
    5094     26236806 :       return verify_gimple_goto (as_a <ggoto *> (stmt));
    5095              : 
    5096      4680511 :     case GIMPLE_SWITCH:
    5097      4680511 :       return verify_gimple_switch (as_a <gswitch *> (stmt));
    5098              : 
    5099    264419515 :     case GIMPLE_RETURN:
    5100    264419515 :       return verify_gimple_return (as_a <greturn *> (stmt));
    5101              : 
    5102              :     case GIMPLE_ASM:
    5103              :       return false;
    5104              : 
    5105        31113 :     case GIMPLE_TRANSACTION:
    5106        31113 :       return verify_gimple_transaction (as_a <gtransaction *> (stmt));
    5107              : 
    5108              :     /* Tuples that do not have tree operands.  */
    5109              :     case GIMPLE_NOP:
    5110              :     case GIMPLE_PREDICT:
    5111              :     case GIMPLE_RESX:
    5112              :     case GIMPLE_EH_DISPATCH:
    5113              :     case GIMPLE_EH_MUST_NOT_THROW:
    5114              :       return false;
    5115              : 
    5116              :     CASE_GIMPLE_OMP:
    5117              :       /* OpenMP directives are validated by the FE and never operated
    5118              :          on by the optimizers.  Furthermore, GIMPLE_OMP_FOR may contain
    5119              :          non-gimple expressions when the main index variable has had
    5120              :          its address taken.  This does not affect the loop itself
    5121              :          because the header of an GIMPLE_OMP_FOR is merely used to determine
    5122              :          how to setup the parallel iteration.  */
    5123              :       return false;
    5124              : 
    5125              :     case GIMPLE_ASSUME:
    5126              :       return false;
    5127              : 
    5128              :     case GIMPLE_DEBUG:
    5129              :       return verify_gimple_debug (stmt);
    5130              : 
    5131            0 :     default:
    5132            0 :       gcc_unreachable ();
    5133              :     }
    5134              : }
    5135              : 
    5136              : /* Verify the contents of a GIMPLE_PHI.  Returns true if there is a problem,
    5137              :    and false otherwise.  */
    5138              : 
    5139              : static bool
    5140    659918588 : verify_gimple_phi (gphi *phi)
    5141              : {
    5142    659918588 :   bool err = false;
    5143    659918588 :   unsigned i;
    5144    659918588 :   tree phi_result = gimple_phi_result (phi);
    5145    659918588 :   bool virtual_p;
    5146              : 
    5147    659918588 :   if (!phi_result)
    5148              :     {
    5149            0 :       error ("invalid %<PHI%> result");
    5150            0 :       return true;
    5151              :     }
    5152              : 
    5153    659918588 :   virtual_p = virtual_operand_p (phi_result);
    5154    659918588 :   if (TREE_CODE (phi_result) != SSA_NAME
    5155    659918588 :       || (virtual_p
    5156    310518919 :           && SSA_NAME_VAR (phi_result) != gimple_vop (cfun)))
    5157              :     {
    5158            0 :       error ("invalid %<PHI%> result");
    5159            0 :       err = true;
    5160              :     }
    5161              : 
    5162   2342079535 :   for (i = 0; i < gimple_phi_num_args (phi); i++)
    5163              :     {
    5164   1682160947 :       tree t = gimple_phi_arg_def (phi, i);
    5165              : 
    5166   1682160947 :       if (!t)
    5167              :         {
    5168            0 :           error ("missing %<PHI%> def");
    5169            0 :           err |= true;
    5170            0 :           continue;
    5171              :         }
    5172              :       /* Addressable variables do have SSA_NAMEs but they
    5173              :          are not considered gimple values.  */
    5174   1682160947 :       else if ((TREE_CODE (t) == SSA_NAME
    5175   1452811392 :                 && virtual_p != virtual_operand_p (t))
    5176   1682160947 :                || (virtual_p
    5177    822069611 :                    && (TREE_CODE (t) != SSA_NAME
    5178    822069611 :                        || SSA_NAME_VAR (t) != gimple_vop (cfun)))
    5179   1682160947 :                || (!virtual_p
    5180    860091336 :                    && !is_gimple_val (t)))
    5181              :         {
    5182            0 :           error ("invalid %<PHI%> argument");
    5183            0 :           debug_generic_expr (t);
    5184            0 :           err |= true;
    5185              :         }
    5186              : #ifdef ENABLE_TYPES_CHECKING
    5187   1682160947 :       if (!useless_type_conversion_p (TREE_TYPE (phi_result), TREE_TYPE (t)))
    5188              :         {
    5189            0 :           error ("incompatible types in %<PHI%> argument %u", i);
    5190            0 :           debug_generic_stmt (TREE_TYPE (phi_result));
    5191            0 :           debug_generic_stmt (TREE_TYPE (t));
    5192            0 :           err |= true;
    5193              :         }
    5194              : #endif
    5195              :     }
    5196              : 
    5197              :   return err;
    5198              : }
    5199              : 
    5200              : /* Verify the GIMPLE statements inside the sequence STMTS.  */
    5201              : 
    5202              : static bool
    5203     57324661 : verify_gimple_in_seq_2 (gimple_seq stmts)
    5204              : {
    5205     57324661 :   gimple_stmt_iterator ittr;
    5206     57324661 :   bool err = false;
    5207              : 
    5208    549625119 :   for (ittr = gsi_start (stmts); !gsi_end_p (ittr); gsi_next (&ittr))
    5209              :     {
    5210    492300458 :       gimple *stmt = gsi_stmt (ittr);
    5211              : 
    5212    492300458 :       switch (gimple_code (stmt))
    5213              :         {
    5214     15195336 :         case GIMPLE_BIND:
    5215     15195336 :           err |= verify_gimple_in_seq_2 (
    5216     15195336 :                    gimple_bind_body (as_a <gbind *> (stmt)));
    5217     15195336 :           break;
    5218              : 
    5219     11782951 :         case GIMPLE_TRY:
    5220     11782951 :           err |= verify_gimple_in_seq_2 (gimple_try_eval (stmt));
    5221     11782951 :           err |= verify_gimple_in_seq_2 (gimple_try_cleanup (stmt));
    5222     11782951 :           break;
    5223              : 
    5224        29082 :         case GIMPLE_EH_FILTER:
    5225        29082 :           err |= verify_gimple_in_seq_2 (gimple_eh_filter_failure (stmt));
    5226        29082 :           break;
    5227              : 
    5228         1732 :         case GIMPLE_EH_ELSE:
    5229         1732 :           {
    5230         1732 :             geh_else *eh_else = as_a <geh_else *> (stmt);
    5231         1732 :             err |= verify_gimple_in_seq_2 (gimple_eh_else_n_body (eh_else));
    5232         1732 :             err |= verify_gimple_in_seq_2 (gimple_eh_else_e_body (eh_else));
    5233              :           }
    5234         1732 :           break;
    5235              : 
    5236       182453 :         case GIMPLE_CATCH:
    5237       182453 :           err |= verify_gimple_in_seq_2 (gimple_catch_handler (
    5238       182453 :                                            as_a <gcatch *> (stmt)));
    5239       182453 :           break;
    5240              : 
    5241          384 :         case GIMPLE_ASSUME:
    5242          384 :           err |= verify_gimple_in_seq_2 (gimple_assume_body (stmt));
    5243          384 :           break;
    5244              : 
    5245         3076 :         case GIMPLE_TRANSACTION:
    5246         3076 :           err |= verify_gimple_transaction (as_a <gtransaction *> (stmt));
    5247         3076 :           break;
    5248              : 
    5249    465105444 :         default:
    5250    465105444 :           {
    5251    465105444 :             bool err2 = verify_gimple_stmt (stmt);
    5252    465105444 :             if (err2)
    5253            1 :               debug_gimple_stmt (stmt);
    5254    465105444 :             err |= err2;
    5255              :           }
    5256              :         }
    5257              :     }
    5258              : 
    5259     57324661 :   return err;
    5260              : }
    5261              : 
    5262              : /* Verify the contents of a GIMPLE_TRANSACTION.  Returns true if there
    5263              :    is a problem, otherwise false.  */
    5264              : 
    5265              : static bool
    5266        34189 : verify_gimple_transaction (gtransaction *stmt)
    5267              : {
    5268        34189 :   tree lab;
    5269              : 
    5270        34189 :   lab = gimple_transaction_label_norm (stmt);
    5271        34189 :   if (lab != NULL && TREE_CODE (lab) != LABEL_DECL)
    5272              :     return true;
    5273        34189 :   lab = gimple_transaction_label_uninst (stmt);
    5274        34189 :   if (lab != NULL && TREE_CODE (lab) != LABEL_DECL)
    5275              :     return true;
    5276        34189 :   lab = gimple_transaction_label_over (stmt);
    5277        34189 :   if (lab != NULL && TREE_CODE (lab) != LABEL_DECL)
    5278              :     return true;
    5279              : 
    5280        34189 :   return verify_gimple_in_seq_2 (gimple_transaction_body (stmt));
    5281              : }
    5282              : 
    5283              : 
    5284              : /* Verify the GIMPLE statements inside the statement list STMTS.  */
    5285              : 
    5286              : DEBUG_FUNCTION bool
    5287     18313851 : verify_gimple_in_seq (gimple_seq stmts, bool ice)
    5288              : {
    5289     18313851 :   timevar_push (TV_TREE_STMT_VERIFY);
    5290     18313851 :   bool res = verify_gimple_in_seq_2 (stmts);
    5291     18313851 :   if (res && ice)
    5292            0 :     internal_error ("%<verify_gimple%> failed");
    5293     18313851 :   timevar_pop (TV_TREE_STMT_VERIFY);
    5294     18313851 :   return res;
    5295              : }
    5296              : 
    5297              : /* Return true when the T can be shared.  */
    5298              : 
    5299              : static bool
    5300  33827530068 : tree_node_can_be_shared (tree t)
    5301              : {
    5302  33827530068 :   if (IS_TYPE_OR_DECL_P (t)
    5303              :       || TREE_CODE (t) == SSA_NAME
    5304              :       || TREE_CODE (t) == IDENTIFIER_NODE
    5305              :       || TREE_CODE (t) == CASE_LABEL_EXPR
    5306              :       || TREE_CODE (t) == OMP_NEXT_VARIANT
    5307  46140731142 :       || is_gimple_min_invariant (t))
    5308              :     return true;
    5309              : 
    5310   4835385151 :   if (t == error_mark_node)
    5311            0 :     return true;
    5312              : 
    5313              :   return false;
    5314              : }
    5315              : 
    5316              : /* Called via walk_tree.  Verify tree sharing.  */
    5317              : 
    5318              : static tree
    5319  33827530068 : verify_node_sharing_1 (tree *tp, int *walk_subtrees, void *data)
    5320              : {
    5321  33827530068 :   hash_set<void *> *visited = (hash_set<void *> *) data;
    5322              : 
    5323  33827530068 :   if (tree_node_can_be_shared (*tp))
    5324              :     {
    5325  28992144917 :       *walk_subtrees = false;
    5326  28992144917 :       return NULL;
    5327              :     }
    5328              : 
    5329   4835385151 :   if (visited->add (*tp))
    5330            0 :     return *tp;
    5331              : 
    5332              :   return NULL;
    5333              : }
    5334              : 
    5335              : /* Called via walk_gimple_stmt.  Verify tree sharing.  */
    5336              : 
    5337              : static tree
    5338  32145369121 : verify_node_sharing (tree *tp, int *walk_subtrees, void *data)
    5339              : {
    5340  32145369121 :   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
    5341  32145369121 :   return verify_node_sharing_1 (tp, walk_subtrees, wi->info);
    5342              : }
    5343              : 
    5344              : static bool eh_error_found;
    5345              : bool
    5346    198322153 : verify_eh_throw_stmt_node (gimple *const &stmt, const int &,
    5347              :                            hash_set<gimple *> *visited)
    5348              : {
    5349    198322153 :   if (!visited->contains (stmt))
    5350              :     {
    5351            0 :       error ("dead statement in EH table");
    5352            0 :       debug_gimple_stmt (stmt);
    5353            0 :       eh_error_found = true;
    5354              :     }
    5355    198322153 :   return true;
    5356              : }
    5357              : 
    5358              : /* Verify if the location LOCs block is in BLOCKS.  */
    5359              : 
    5360              : static bool
    5361  23725300909 : verify_location (hash_set<tree> *blocks, location_t loc)
    5362              : {
    5363  38484740968 :   tree block = LOCATION_BLOCK (loc);
    5364  38484740968 :   if (block != NULL_TREE
    5365  38484740968 :       && !blocks->contains (block))
    5366              :     {
    5367            0 :       error ("location references block not in block tree");
    5368            0 :       return true;
    5369              :     }
    5370  38484740968 :   if (block != NULL_TREE)
    5371  14759440059 :     return verify_location (blocks, BLOCK_SOURCE_LOCATION (block));
    5372              :   return false;
    5373              : }
    5374              : 
    5375              : /* Called via walk_tree.  Verify that expressions have no blocks.  */
    5376              : 
    5377              : static tree
    5378   1673040724 : verify_expr_no_block (tree *tp, int *walk_subtrees, void *)
    5379              : {
    5380   1673040724 :   if (!EXPR_P (*tp))
    5381              :     {
    5382    999855608 :       *walk_subtrees = false;
    5383    999855608 :       return NULL;
    5384              :     }
    5385              : 
    5386    673185116 :   location_t loc = EXPR_LOCATION (*tp);
    5387    673185116 :   if (LOCATION_BLOCK (loc) != NULL)
    5388            0 :     return *tp;
    5389              : 
    5390              :   return NULL;
    5391              : }
    5392              : 
    5393              : /* Called via walk_tree.  Verify locations of expressions.  */
    5394              : 
    5395              : static tree
    5396  37754825063 : verify_expr_location_1 (tree *tp, int *walk_subtrees, void *data)
    5397              : {
    5398  37754825063 :   hash_set<tree> *blocks = (hash_set<tree> *) data;
    5399  37754825063 :   tree t = *tp;
    5400              : 
    5401              :   /* ???  This doesn't really belong here but there's no good place to
    5402              :      stick this remainder of old verify_expr.  */
    5403              :   /* ???  This barfs on debug stmts which contain binds to vars with
    5404              :      different function context.  */
    5405              : #if 0
    5406              :   if (VAR_P (t)
    5407              :       || TREE_CODE (t) == PARM_DECL
    5408              :       || TREE_CODE (t) == RESULT_DECL)
    5409              :     {
    5410              :       tree context = decl_function_context (t);
    5411              :       if (context != cfun->decl
    5412              :           && !SCOPE_FILE_SCOPE_P (context)
    5413              :           && !TREE_STATIC (t)
    5414              :           && !DECL_EXTERNAL (t))
    5415              :         {
    5416              :           error ("local declaration from a different function");
    5417              :           return t;
    5418              :         }
    5419              :     }
    5420              : #endif
    5421              : 
    5422  37754825063 :   if (VAR_P (t) && DECL_HAS_DEBUG_EXPR_P (t))
    5423              :     {
    5424    434934942 :       tree x = DECL_DEBUG_EXPR (t);
    5425    434934942 :       tree addr = walk_tree (&x, verify_expr_no_block, NULL, NULL);
    5426    434934942 :       if (addr)
    5427            0 :         return addr;
    5428              :     }
    5429  37754825063 :   if ((VAR_P (t)
    5430              :        || TREE_CODE (t) == PARM_DECL
    5431              :        || TREE_CODE (t) == RESULT_DECL)
    5432   8532783820 :       && DECL_HAS_VALUE_EXPR_P (t))
    5433              :     {
    5434         1938 :       tree x = DECL_VALUE_EXPR (t);
    5435         1938 :       tree addr = walk_tree (&x, verify_expr_no_block, NULL, NULL);
    5436         1938 :       if (addr)
    5437            0 :         return addr;
    5438              :     }
    5439              : 
    5440  37754825063 :   if (!EXPR_P (t))
    5441              :     {
    5442  29791485564 :       *walk_subtrees = false;
    5443  29791485564 :       return NULL;
    5444              :     }
    5445              : 
    5446   7963339499 :   location_t loc = EXPR_LOCATION (t);
    5447   7963339499 :   if (verify_location (blocks, loc))
    5448            0 :     return t;
    5449              : 
    5450              :   return NULL;
    5451              : }
    5452              : 
    5453              : /* Called via walk_gimple_op.  Verify locations of expressions.  */
    5454              : 
    5455              : static tree
    5456  36043000055 : verify_expr_location (tree *tp, int *walk_subtrees, void *data)
    5457              : {
    5458  36043000055 :   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
    5459  36043000055 :   return verify_expr_location_1 (tp, walk_subtrees, wi->info);
    5460              : }
    5461              : 
    5462              : /* Insert all subblocks of BLOCK into BLOCKS and recurse.  */
    5463              : 
    5464              : static void
    5465   2521461317 : collect_subblocks (hash_set<tree> *blocks, tree block)
    5466              : {
    5467   2521461317 :   tree t;
    5468   4790272368 :   for (t = BLOCK_SUBBLOCKS (block); t; t = BLOCK_CHAIN (t))
    5469              :     {
    5470   2268811051 :       blocks->add (t);
    5471   2268811051 :       collect_subblocks (blocks, t);
    5472              :     }
    5473   2521461317 : }
    5474              : 
    5475              : /* Disable warnings about missing quoting in GCC diagnostics for
    5476              :    the verification errors.  Their format strings don't follow
    5477              :    GCC diagnostic conventions and trigger an ICE in the end.  */
    5478              : #if __GNUC__ >= 10
    5479              : #  pragma GCC diagnostic push
    5480              : #  pragma GCC diagnostic ignored "-Wformat-diag"
    5481              : #endif
    5482              : 
    5483              : /* Verify the GIMPLE statements in the CFG of FN.  */
    5484              : 
    5485              : DEBUG_FUNCTION bool
    5486    252650266 : verify_gimple_in_cfg (struct function *fn, bool verify_nothrow, bool ice)
    5487              : {
    5488    252650266 :   basic_block bb;
    5489    252650266 :   bool err = false;
    5490              : 
    5491    252650266 :   timevar_push (TV_TREE_STMT_VERIFY);
    5492    252650266 :   hash_set<void *> visited;
    5493    252650266 :   hash_set<gimple *> visited_throwing_stmts;
    5494              : 
    5495              :   /* Collect all BLOCKs referenced by the BLOCK tree of FN.  */
    5496    252650266 :   hash_set<tree> blocks;
    5497    252650266 :   if (DECL_INITIAL (fn->decl))
    5498              :     {
    5499    252650266 :       blocks.add (DECL_INITIAL (fn->decl));
    5500    252650266 :       collect_subblocks (&blocks, DECL_INITIAL (fn->decl));
    5501              :     }
    5502              : 
    5503   2252102897 :   FOR_EACH_BB_FN (bb, fn)
    5504              :     {
    5505   1999452631 :       gimple_stmt_iterator gsi;
    5506   1999452631 :       edge_iterator ei;
    5507   1999452631 :       edge e;
    5508              : 
    5509   1999452631 :       for (gphi_iterator gpi = gsi_start_phis (bb);
    5510   2659371219 :            !gsi_end_p (gpi);
    5511    659918588 :            gsi_next (&gpi))
    5512              :         {
    5513    659918588 :           gphi *phi = gpi.phi ();
    5514    659918588 :           bool err2 = false;
    5515    659918588 :           unsigned i;
    5516              : 
    5517    659918588 :           if (gimple_bb (phi) != bb)
    5518              :             {
    5519            0 :               error ("gimple_bb (phi) is set to a wrong basic block");
    5520            0 :               err2 = true;
    5521              :             }
    5522              : 
    5523    659918588 :           err2 |= verify_gimple_phi (phi);
    5524              : 
    5525              :           /* Only PHI arguments have locations.  */
    5526    659918588 :           if (gimple_location (phi) != UNKNOWN_LOCATION)
    5527              :             {
    5528            0 :               error ("PHI node with location");
    5529            0 :               err2 = true;
    5530              :             }
    5531              : 
    5532   2342079535 :           for (i = 0; i < gimple_phi_num_args (phi); i++)
    5533              :             {
    5534   1682160947 :               tree arg = gimple_phi_arg_def (phi, i);
    5535   1682160947 :               tree addr = walk_tree (&arg, verify_node_sharing_1,
    5536              :                                      &visited, NULL);
    5537   1682160947 :               if (addr)
    5538              :                 {
    5539            0 :                   error ("incorrect sharing of tree nodes");
    5540            0 :                   debug_generic_expr (addr);
    5541            0 :                   err2 |= true;
    5542              :                 }
    5543   1682160947 :               location_t loc = gimple_phi_arg_location (phi, i);
    5544   1682160947 :               if (virtual_operand_p (gimple_phi_result (phi))
    5545   1682160947 :                   && loc != UNKNOWN_LOCATION)
    5546              :                 {
    5547            0 :                   error ("virtual PHI with argument locations");
    5548            0 :                   err2 = true;
    5549              :                 }
    5550   1682160947 :               addr = walk_tree (&arg, verify_expr_location_1, &blocks, NULL);
    5551   1682160947 :               if (addr)
    5552              :                 {
    5553            0 :                   debug_generic_expr (addr);
    5554            0 :                   err2 = true;
    5555              :                 }
    5556   1682160947 :               err2 |= verify_location (&blocks, loc);
    5557              :             }
    5558              : 
    5559    659918588 :           if (err2)
    5560            0 :             debug_gimple_stmt (phi);
    5561    659918588 :           err |= err2;
    5562              :         }
    5563              : 
    5564  17537109640 :       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    5565              :         {
    5566  13538204378 :           gimple *stmt = gsi_stmt (gsi);
    5567  13538204378 :           bool err2 = false;
    5568  13538204378 :           struct walk_stmt_info wi;
    5569  13538204378 :           tree addr;
    5570  13538204378 :           int lp_nr;
    5571              : 
    5572  13538204378 :           if (gimple_bb (stmt) != bb)
    5573              :             {
    5574            0 :               error ("gimple_bb (stmt) is set to a wrong basic block");
    5575            0 :               err2 = true;
    5576              :             }
    5577              : 
    5578  13538204378 :           err2 |= verify_gimple_stmt (stmt);
    5579  13538204378 :           err2 |= verify_location (&blocks, gimple_location (stmt));
    5580              : 
    5581  13538204378 :           memset (&wi, 0, sizeof (wi));
    5582  13538204378 :           wi.info = (void *) &visited;
    5583  13538204378 :           addr = walk_gimple_op (stmt, verify_node_sharing, &wi);
    5584  13538204378 :           if (addr)
    5585              :             {
    5586            0 :               error ("incorrect sharing of tree nodes");
    5587            0 :               debug_generic_expr (addr);
    5588            0 :               err2 |= true;
    5589              :             }
    5590              : 
    5591  13538204378 :           memset (&wi, 0, sizeof (wi));
    5592  13538204378 :           wi.info = (void *) &blocks;
    5593  13538204378 :           addr = walk_gimple_op (stmt, verify_expr_location, &wi);
    5594  13538204378 :           if (addr)
    5595              :             {
    5596            0 :               debug_generic_expr (addr);
    5597            0 :               err2 |= true;
    5598              :             }
    5599              : 
    5600              :           /* If the statement is marked as part of an EH region, then it is
    5601              :              expected that the statement could throw.  Verify that when we
    5602              :              have optimizations that simplify statements such that we prove
    5603              :              that they cannot throw, that we update other data structures
    5604              :              to match.  */
    5605  13538204378 :           lp_nr = lookup_stmt_eh_lp (stmt);
    5606  13538204378 :           if (lp_nr != 0)
    5607    198322153 :             visited_throwing_stmts.add (stmt);
    5608    198322153 :           if (lp_nr > 0)
    5609              :             {
    5610    190563258 :               if (!stmt_could_throw_p (cfun, stmt))
    5611              :                 {
    5612           24 :                   if (verify_nothrow)
    5613              :                     {
    5614            0 :                       error ("statement marked for throw, but doesn%'t");
    5615            0 :                       err2 |= true;
    5616              :                     }
    5617              :                 }
    5618    190563234 :               else if (!gsi_one_before_end_p (gsi))
    5619              :                 {
    5620            0 :                   error ("statement marked for throw in middle of block");
    5621            0 :                   err2 |= true;
    5622              :                 }
    5623              :             }
    5624              : 
    5625  13538204378 :           if (err2)
    5626            0 :             debug_gimple_stmt (stmt);
    5627  13538204378 :           err |= err2;
    5628              :         }
    5629              : 
    5630   4761423593 :       FOR_EACH_EDGE (e, ei, bb->succs)
    5631   2761970962 :         if (e->goto_locus != UNKNOWN_LOCATION)
    5632    541596085 :           err |= verify_location (&blocks, e->goto_locus);
    5633              :     }
    5634              : 
    5635    252650266 :   hash_map<gimple *, int> *eh_table = get_eh_throw_stmt_table (cfun);
    5636    252650266 :   eh_error_found = false;
    5637    252650266 :   if (eh_table)
    5638     37931311 :     eh_table->traverse<hash_set<gimple *> *, verify_eh_throw_stmt_node>
    5639    236253464 :       (&visited_throwing_stmts);
    5640              : 
    5641    252650266 :   if (ice && (err || eh_error_found))
    5642            0 :     internal_error ("verify_gimple failed");
    5643              : 
    5644    252650266 :   verify_histograms ();
    5645    252650266 :   timevar_pop (TV_TREE_STMT_VERIFY);
    5646              : 
    5647    252650266 :   return (err || eh_error_found);
    5648    252650266 : }
    5649              : 
    5650              : 
    5651              : /* Verifies that the flow information is OK.  */
    5652              : 
    5653              : static bool
    5654    236356927 : gimple_verify_flow_info (void)
    5655              : {
    5656    236356927 :   bool err = false;
    5657    236356927 :   basic_block bb;
    5658    236356927 :   gimple_stmt_iterator gsi;
    5659    236356927 :   gimple *stmt;
    5660    236356927 :   edge e;
    5661    236356927 :   edge_iterator ei;
    5662              : 
    5663    236356927 :   if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->il.gimple.seq
    5664    236356927 :       || ENTRY_BLOCK_PTR_FOR_FN (cfun)->il.gimple.phi_nodes)
    5665              :     {
    5666            0 :       error ("ENTRY_BLOCK has IL associated with it");
    5667            0 :       err = true;
    5668              :     }
    5669              : 
    5670    236356927 :   if (EXIT_BLOCK_PTR_FOR_FN (cfun)->il.gimple.seq
    5671    236356927 :       || EXIT_BLOCK_PTR_FOR_FN (cfun)->il.gimple.phi_nodes)
    5672              :     {
    5673            0 :       error ("EXIT_BLOCK has IL associated with it");
    5674            0 :       err = true;
    5675              :     }
    5676              : 
    5677    468704730 :   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
    5678    232347803 :     if (e->flags & EDGE_FALLTHRU)
    5679              :       {
    5680            0 :         error ("fallthru to exit from bb %d", e->src->index);
    5681            0 :         err = true;
    5682              :       }
    5683    236356927 :   if (cfun->cfg->full_profile
    5684    236356927 :       && !ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.initialized_p ())
    5685              :     {
    5686            0 :       error ("entry block count not initialized");
    5687            0 :       err = true;
    5688              :     }
    5689    236356927 :   if (cfun->cfg->full_profile
    5690    236356927 :       && !EXIT_BLOCK_PTR_FOR_FN (cfun)->count.initialized_p ())
    5691              :     {
    5692            0 :       error ("exit block count not initialized");
    5693            0 :       err = true;
    5694              :     }
    5695    236356927 :   if (cfun->cfg->full_profile
    5696    356044773 :       && !single_succ_edge
    5697    119687846 :               (ENTRY_BLOCK_PTR_FOR_FN (cfun))->probability.initialized_p ())
    5698              :     {
    5699            0 :       error ("probability of edge from entry block not initialized");
    5700            0 :       err = true;
    5701              :     }
    5702    236356927 :   if (!EXIT_BLOCK_PTR_FOR_FN (cfun)
    5703    236356927 :         ->count.compatible_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count))
    5704              :     {
    5705            0 :       error ("exit block count is not compatible with entry block count");
    5706            0 :       err = true;
    5707              :     }
    5708              : 
    5709              : 
    5710   2260135496 :   FOR_EACH_BB_FN (bb, cfun)
    5711              :     {
    5712   2023778569 :       bool found_ctrl_stmt = false;
    5713              : 
    5714   2023778569 :       stmt = NULL;
    5715              : 
    5716   2023778569 :       if (cfun->cfg->full_profile)
    5717              :         {
    5718   1328397080 :           if (!bb->count.initialized_p ())
    5719              :             {
    5720            0 :               error ("count of bb %d not initialized", bb->index);
    5721            0 :               err = true;
    5722              :             }
    5723   3201167341 :           FOR_EACH_EDGE (e, ei, bb->succs)
    5724   1872770261 :             if (!e->probability.initialized_p ())
    5725              :               {
    5726            0 :                 error ("probability of edge %d->%d not initialized",
    5727            0 :                        bb->index, e->dest->index);
    5728            0 :                 err = true;
    5729              :               }
    5730              :         }
    5731   2023778569 :       if (!bb->count.compatible_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count))
    5732              :         {
    5733            0 :           error ("count of bb %d is not compatible with entry block count",
    5734              :                  bb->index);
    5735            0 :           err = true;
    5736              :         }
    5737              : 
    5738              :       /* Skip labels on the start of basic block.  */
    5739   4195019281 :       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    5740              :         {
    5741   2018046052 :           tree label;
    5742   2018046052 :           gimple *prev_stmt = stmt;
    5743              : 
    5744   2018046052 :           stmt = gsi_stmt (gsi);
    5745              : 
    5746   2018046052 :           if (gimple_code (stmt) != GIMPLE_LABEL)
    5747              :             break;
    5748              : 
    5749    147462143 :           label = gimple_label_label (as_a <glabel *> (stmt));
    5750    147462143 :           if (prev_stmt && DECL_NONLOCAL (label))
    5751              :             {
    5752            0 :               error ("nonlocal label %qD is not first in a sequence "
    5753              :                      "of labels in bb %d", label, bb->index);
    5754            0 :               err = true;
    5755              :             }
    5756              : 
    5757    150197098 :           if (prev_stmt && EH_LANDING_PAD_NR (label) != 0)
    5758              :             {
    5759            0 :               error ("EH landing pad label %qD is not first in a sequence "
    5760              :                      "of labels in bb %d", label, bb->index);
    5761            0 :               err = true;
    5762              :             }
    5763              : 
    5764    147462143 :           if (label_to_block (cfun, label) != bb)
    5765              :             {
    5766            0 :               error ("label %qD to block does not match in bb %d",
    5767              :                      label, bb->index);
    5768            0 :               err = true;
    5769              :             }
    5770              : 
    5771    147462143 :           if (decl_function_context (label) != current_function_decl)
    5772              :             {
    5773            0 :               error ("label %qD has incorrect context in bb %d",
    5774              :                      label, bb->index);
    5775            0 :               err = true;
    5776              :             }
    5777              :         }
    5778              : 
    5779              :       /* Verify that body of basic block BB is free of control flow.  */
    5780   2023778569 :       bool seen_nondebug_stmt = false;
    5781  16646427404 :       for (; !gsi_end_p (gsi); gsi_next (&gsi))
    5782              :         {
    5783  14622648835 :           gimple *stmt = gsi_stmt (gsi);
    5784              : 
    5785              :           /* Do NOT disregard debug stmts after found_ctrl_stmt.  */
    5786  14622648835 :           if (found_ctrl_stmt)
    5787              :             {
    5788            0 :               error ("control flow in the middle of basic block %d",
    5789              :                      bb->index);
    5790            0 :               err = true;
    5791              :             }
    5792              : 
    5793  14622648835 :           if (stmt_ends_bb_p (stmt))
    5794   1370748373 :             found_ctrl_stmt = true;
    5795              : 
    5796  14622648835 :           if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
    5797              :             {
    5798            0 :               error ("label %qD in the middle of basic block %d",
    5799              :                      gimple_label_label (label_stmt), bb->index);
    5800            0 :               err = true;
    5801              :             }
    5802              : 
    5803              :           /* Check that no statements appear between a returns_twice call
    5804              :              and its associated abnormal edge.  */
    5805  14622648835 :           if (gimple_code (stmt) == GIMPLE_CALL
    5806  14622648835 :               && gimple_call_flags (stmt) & ECF_RETURNS_TWICE)
    5807              :             {
    5808       148978 :               bool misplaced = false;
    5809              :               /* TM is an exception: it points abnormal edges just after the
    5810              :                  call that starts a transaction, i.e. it must end the BB.  */
    5811       148978 :               if (gimple_call_builtin_p (stmt, BUILT_IN_TM_START))
    5812              :                 {
    5813         3779 :                   if (single_succ_p (bb)
    5814         2989 :                       && bb_has_abnormal_pred (single_succ (bb))
    5815         6121 :                       && !gsi_one_nondebug_before_end_p (gsi))
    5816              :                     {
    5817            0 :                       error ("returns_twice call is not last in basic block "
    5818              :                              "%d", bb->index);
    5819            0 :                       misplaced = true;
    5820              :                     }
    5821              :                 }
    5822              :               else
    5823              :                 {
    5824       145199 :                   if (seen_nondebug_stmt && bb_has_abnormal_pred (bb))
    5825              :                     {
    5826            0 :                       error ("returns_twice call is not first in basic block "
    5827              :                              "%d", bb->index);
    5828            0 :                       misplaced = true;
    5829              :                     }
    5830              :                 }
    5831            0 :               if (misplaced)
    5832              :                 {
    5833            0 :                   print_gimple_stmt (stderr, stmt, 0, TDF_SLIM);
    5834            0 :                   err = true;
    5835              :                 }
    5836              :             }
    5837  14622648835 :           if (!is_gimple_debug (stmt))
    5838   6664466279 :             seen_nondebug_stmt = true;
    5839              :         }
    5840              : 
    5841   2023778569 :       gsi = gsi_last_nondebug_bb (bb);
    5842   2023778569 :       if (gsi_end_p (gsi))
    5843    123906322 :         continue;
    5844              : 
    5845   1899872247 :       stmt = gsi_stmt (gsi);
    5846              : 
    5847   1899872247 :       if (gimple_code (stmt) == GIMPLE_LABEL)
    5848     41359218 :         continue;
    5849              : 
    5850   1858513029 :       if (verify_eh_edges (stmt))
    5851            0 :         err = true;
    5852              : 
    5853   1858513029 :       if (is_ctrl_stmt (stmt))
    5854              :         {
    5855   2894218535 :           FOR_EACH_EDGE (e, ei, bb->succs)
    5856   1834625122 :             if (e->flags & EDGE_FALLTHRU)
    5857              :               {
    5858            0 :                 error ("fallthru edge after a control statement in bb %d",
    5859              :                        bb->index);
    5860            0 :                 err = true;
    5861              :               }
    5862              :         }
    5863              : 
    5864   1858513029 :       if (gimple_code (stmt) != GIMPLE_COND)
    5865              :         {
    5866              :           /* Verify that there are no edges with EDGE_TRUE/FALSE_FLAG set
    5867              :              after anything else but if statement.  */
    5868   2193916892 :           FOR_EACH_EDGE (e, ei, bb->succs)
    5869   1109522227 :             if (e->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE))
    5870              :               {
    5871            0 :                 error ("true/false edge after a non-GIMPLE_COND in bb %d",
    5872              :                        bb->index);
    5873            0 :                 err = true;
    5874              :               }
    5875              :         }
    5876              : 
    5877   1858513029 :       switch (gimple_code (stmt))
    5878              :         {
    5879    774118364 :         case GIMPLE_COND:
    5880    774118364 :           {
    5881    774118364 :             edge true_edge;
    5882    774118364 :             edge false_edge;
    5883              : 
    5884    774118364 :             extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
    5885              : 
    5886    774118364 :             if (!true_edge
    5887    774118364 :                 || !false_edge
    5888    774118364 :                 || !(true_edge->flags & EDGE_TRUE_VALUE)
    5889    774118364 :                 || !(false_edge->flags & EDGE_FALSE_VALUE)
    5890    774118364 :                 || (true_edge->flags & (EDGE_FALLTHRU | EDGE_ABNORMAL))
    5891    774118364 :                 || (false_edge->flags & (EDGE_FALLTHRU | EDGE_ABNORMAL))
    5892   1548236728 :                 || EDGE_COUNT (bb->succs) >= 3)
    5893              :               {
    5894            0 :                 error ("wrong outgoing edge flags at end of bb %d",
    5895              :                        bb->index);
    5896            0 :                 err = true;
    5897              :               }
    5898              :           }
    5899    774118364 :           break;
    5900              : 
    5901        50189 :         case GIMPLE_GOTO:
    5902        50189 :           if (simple_goto_p (stmt))
    5903              :             {
    5904            0 :               error ("explicit goto at end of bb %d", bb->index);
    5905            0 :               err = true;
    5906              :             }
    5907              :           else
    5908              :             {
    5909              :               /* FIXME.  We should double check that the labels in the
    5910              :                  destination blocks have their address taken.  */
    5911       178614 :               FOR_EACH_EDGE (e, ei, bb->succs)
    5912       128425 :                 if ((e->flags & (EDGE_FALLTHRU | EDGE_TRUE_VALUE
    5913              :                                  | EDGE_FALSE_VALUE))
    5914       128425 :                     || !(e->flags & EDGE_ABNORMAL))
    5915              :                   {
    5916            0 :                     error ("wrong outgoing edge flags at end of bb %d",
    5917              :                            bb->index);
    5918            0 :                     err = true;
    5919              :                   }
    5920              :             }
    5921              :           break;
    5922              : 
    5923    395786259 :         case GIMPLE_CALL:
    5924    395786259 :           if (!gimple_call_builtin_p (stmt, BUILT_IN_RETURN))
    5925              :             break;
    5926              :           /* fallthru */
    5927    232343379 :         case GIMPLE_RETURN:
    5928    232343379 :           if (!single_succ_p (bb)
    5929    232343379 :               || (single_succ_edge (bb)->flags
    5930    232343379 :                   & (EDGE_FALLTHRU | EDGE_ABNORMAL
    5931              :                      | EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
    5932              :             {
    5933            0 :               error ("wrong outgoing edge flags at end of bb %d", bb->index);
    5934            0 :               err = true;
    5935              :             }
    5936    232343379 :           if (single_succ (bb) != EXIT_BLOCK_PTR_FOR_FN (cfun))
    5937              :             {
    5938            0 :               error ("return edge does not point to exit in bb %d",
    5939              :                      bb->index);
    5940            0 :               err = true;
    5941              :             }
    5942              :           break;
    5943              : 
    5944      4214412 :         case GIMPLE_SWITCH:
    5945      4214412 :           {
    5946      4214412 :             gswitch *switch_stmt = as_a <gswitch *> (stmt);
    5947      4214412 :             tree prev;
    5948      4214412 :             edge e;
    5949      4214412 :             size_t i, n;
    5950              : 
    5951      4214412 :             n = gimple_switch_num_labels (switch_stmt);
    5952              : 
    5953              :             /* Mark all the destination basic blocks.  */
    5954     33425495 :             for (i = 0; i < n; ++i)
    5955              :               {
    5956     29211083 :                 basic_block label_bb = gimple_switch_label_bb (cfun, switch_stmt, i);
    5957     29211083 :                 gcc_assert (!label_bb->aux || label_bb->aux == (void *)1);
    5958     29211083 :                 label_bb->aux = (void *)1;
    5959              :               }
    5960              : 
    5961              :             /* Verify that the case labels are sorted.  */
    5962      4214412 :             prev = gimple_switch_label (switch_stmt, 0);
    5963     29211083 :             for (i = 1; i < n; ++i)
    5964              :               {
    5965     24996671 :                 tree c = gimple_switch_label (switch_stmt, i);
    5966     24996671 :                 if (!CASE_LOW (c))
    5967              :                   {
    5968            0 :                     error ("found default case not at the start of "
    5969              :                            "case vector");
    5970            0 :                     err = true;
    5971            0 :                     continue;
    5972              :                   }
    5973     24996671 :                 if (CASE_LOW (prev)
    5974     24996671 :                     && !tree_int_cst_lt (CASE_LOW (prev), CASE_LOW (c)))
    5975              :                   {
    5976            0 :                     error ("case labels not sorted: ");
    5977            0 :                     print_generic_expr (stderr, prev);
    5978            0 :                     fprintf (stderr," is greater than ");
    5979            0 :                     print_generic_expr (stderr, c);
    5980            0 :                     fprintf (stderr," but comes before it.\n");
    5981            0 :                     err = true;
    5982              :                   }
    5983              :                 prev = c;
    5984              :               }
    5985              :             /* VRP will remove the default case if it can prove it will
    5986              :                never be executed.  So do not verify there always exists
    5987              :                a default case here.  */
    5988              : 
    5989     29921312 :             FOR_EACH_EDGE (e, ei, bb->succs)
    5990              :               {
    5991     25706900 :                 if (!e->dest->aux)
    5992              :                   {
    5993            0 :                     error ("extra outgoing edge %d->%d",
    5994              :                            bb->index, e->dest->index);
    5995            0 :                     err = true;
    5996              :                   }
    5997              : 
    5998     25706900 :                 e->dest->aux = (void *)2;
    5999     25706900 :                 if ((e->flags & (EDGE_FALLTHRU | EDGE_ABNORMAL
    6000              :                                  | EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
    6001              :                   {
    6002            0 :                     error ("wrong outgoing edge flags at end of bb %d",
    6003              :                            bb->index);
    6004            0 :                     err = true;
    6005              :                   }
    6006              :               }
    6007              : 
    6008              :             /* Check that we have all of them.  */
    6009     33425495 :             for (i = 0; i < n; ++i)
    6010              :               {
    6011     29211083 :                 basic_block label_bb = gimple_switch_label_bb (cfun,
    6012              :                                                                switch_stmt, i);
    6013              : 
    6014     29211083 :                 if (label_bb->aux != (void *)2)
    6015              :                   {
    6016            0 :                     error ("missing edge %i->%i", bb->index, label_bb->index);
    6017            0 :                     err = true;
    6018              :                   }
    6019              :               }
    6020              : 
    6021     29921312 :             FOR_EACH_EDGE (e, ei, bb->succs)
    6022     25706900 :               e->dest->aux = (void *)0;
    6023              :           }
    6024      4214412 :           break;
    6025              : 
    6026      1928617 :         case GIMPLE_EH_DISPATCH:
    6027      1928617 :           if (verify_eh_dispatch_edge (as_a <geh_dispatch *> (stmt)))
    6028            0 :             err = true;
    6029              :           break;
    6030              : 
    6031              :         default:
    6032              :           break;
    6033              :         }
    6034              :     }
    6035              : 
    6036    236356927 :   if (dom_info_state (CDI_DOMINATORS) >= DOM_NO_FAST_QUERY)
    6037    192308934 :     verify_dominators (CDI_DOMINATORS);
    6038              : 
    6039    236356927 :   return err;
    6040              : }
    6041              : 
    6042              : #if __GNUC__ >= 10
    6043              : #  pragma GCC diagnostic pop
    6044              : #endif
    6045              : 
    6046              : /* Updates phi nodes after creating a forwarder block joined
    6047              :    by edge FALLTHRU.  */
    6048              : 
    6049              : static void
    6050        93286 : gimple_make_forwarder_block (edge fallthru)
    6051              : {
    6052        93286 :   edge e;
    6053        93286 :   edge_iterator ei;
    6054        93286 :   basic_block dummy, bb;
    6055        93286 :   tree var;
    6056        93286 :   gphi_iterator gsi;
    6057        93286 :   bool forward_location_p;
    6058              : 
    6059        93286 :   dummy = fallthru->src;
    6060        93286 :   bb = fallthru->dest;
    6061              : 
    6062        93286 :   if (single_pred_p (bb))
    6063          201 :     return;
    6064              : 
    6065              :   /* We can forward location info if we have only one predecessor.  */
    6066        93085 :   forward_location_p = single_pred_p (dummy);
    6067              : 
    6068              :   /* If we redirected a branch we must create new PHI nodes at the
    6069              :      start of BB.  */
    6070       317039 :   for (gsi = gsi_start_phis (dummy); !gsi_end_p (gsi); gsi_next (&gsi))
    6071              :     {
    6072       223954 :       gphi *phi, *new_phi;
    6073              : 
    6074       223954 :       phi = gsi.phi ();
    6075       223954 :       var = gimple_phi_result (phi);
    6076       223954 :       new_phi = create_phi_node (var, bb);
    6077       223954 :       gimple_phi_set_result (phi, copy_ssa_name (var, phi));
    6078       223958 :       add_phi_arg (new_phi, gimple_phi_result (phi), fallthru,
    6079              :                    forward_location_p
    6080            4 :                    ? gimple_phi_arg_location (phi, 0) : UNKNOWN_LOCATION);
    6081              :     }
    6082              : 
    6083              :   /* Add the arguments we have stored on edges.  */
    6084       282059 :   FOR_EACH_EDGE (e, ei, bb->preds)
    6085              :     {
    6086       188974 :       if (e == fallthru)
    6087        93085 :         continue;
    6088              : 
    6089        95889 :       flush_pending_stmts (e);
    6090              :     }
    6091              : }
    6092              : 
    6093              : 
    6094              : /* Return a non-special label in the head of basic block BLOCK.
    6095              :    Create one if it doesn't exist.  */
    6096              : 
    6097              : tree
    6098      5904984 : gimple_block_label (basic_block bb)
    6099              : {
    6100      5904984 :   gimple_stmt_iterator i, s = gsi_start_bb (bb);
    6101      5904984 :   bool first = true;
    6102      5904984 :   tree label;
    6103      5904984 :   glabel *stmt;
    6104              : 
    6105      5904984 :   for (i = s; !gsi_end_p (i); first = false, gsi_next (&i))
    6106              :     {
    6107      4828829 :       stmt = dyn_cast <glabel *> (gsi_stmt (i));
    6108      4737945 :       if (!stmt)
    6109              :         break;
    6110      4737945 :       label = gimple_label_label (stmt);
    6111      4737945 :       if (!DECL_NONLOCAL (label))
    6112              :         {
    6113      4737945 :           if (!first)
    6114            0 :             gsi_move_before (&i, &s);
    6115              :           return label;
    6116              :         }
    6117              :     }
    6118              : 
    6119      1167039 :   label = create_artificial_label (UNKNOWN_LOCATION);
    6120      1167039 :   stmt = gimple_build_label (label);
    6121      1167039 :   gsi_insert_before (&s, stmt, GSI_NEW_STMT);
    6122      1167039 :   return label;
    6123              : }
    6124              : 
    6125              : 
    6126              : /* Attempt to perform edge redirection by replacing a possibly complex
    6127              :    jump instruction by a goto or by removing the jump completely.
    6128              :    This can apply only if all edges now point to the same block.  The
    6129              :    parameters and return values are equivalent to
    6130              :    redirect_edge_and_branch.  */
    6131              : 
    6132              : static edge
    6133     63324077 : gimple_try_redirect_by_replacing_jump (edge e, basic_block target)
    6134              : {
    6135     63324077 :   basic_block src = e->src;
    6136     63324077 :   gimple_stmt_iterator i;
    6137     63324077 :   gimple *stmt;
    6138              : 
    6139              :   /* We can replace or remove a complex jump only when we have exactly
    6140              :      two edges.  */
    6141     63324077 :   if (EDGE_COUNT (src->succs) != 2
    6142              :       /* Verify that all targets will be TARGET.  Specifically, the
    6143              :          edge that is not E must also go to TARGET.  */
    6144     63324077 :       || EDGE_SUCC (src, EDGE_SUCC (src, 0) == e)->dest != target)
    6145              :     return NULL;
    6146              : 
    6147       421220 :   i = gsi_last_bb (src);
    6148       421220 :   if (gsi_end_p (i))
    6149              :     return NULL;
    6150              : 
    6151       421220 :   stmt = gsi_stmt (i);
    6152              : 
    6153       421220 :   if (gimple_code (stmt) == GIMPLE_COND || gimple_code (stmt) == GIMPLE_SWITCH)
    6154              :     {
    6155       421190 :       gsi_remove (&i, true);
    6156       421190 :       e = ssa_redirect_edge (e, target);
    6157       421190 :       e->flags = EDGE_FALLTHRU;
    6158       421190 :       return e;
    6159              :     }
    6160              : 
    6161              :   return NULL;
    6162              : }
    6163              : 
    6164              : 
    6165              : /* Redirect E to DEST.  Return NULL on failure.  Otherwise, return the
    6166              :    edge representing the redirected branch.  */
    6167              : 
    6168              : static edge
    6169     64616011 : gimple_redirect_edge_and_branch (edge e, basic_block dest)
    6170              : {
    6171     64616011 :   basic_block bb = e->src;
    6172     64616011 :   gimple_stmt_iterator gsi;
    6173     64616011 :   edge ret;
    6174     64616011 :   gimple *stmt;
    6175              : 
    6176     64616011 :   if (e->flags & EDGE_ABNORMAL)
    6177              :     return NULL;
    6178              : 
    6179     64616011 :   if (e->dest == dest)
    6180              :     return NULL;
    6181              : 
    6182     64586404 :   if (e->flags & EDGE_EH)
    6183      1000644 :     return redirect_eh_edge (e, dest);
    6184              : 
    6185     63585760 :   if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
    6186              :     {
    6187     63324077 :       ret = gimple_try_redirect_by_replacing_jump (e, dest);
    6188     63324077 :       if (ret)
    6189              :         return ret;
    6190              :     }
    6191              : 
    6192     63164570 :   gsi = gsi_last_nondebug_bb (bb);
    6193     63164570 :   stmt = gsi_end_p (gsi) ? NULL : gsi_stmt (gsi);
    6194              : 
    6195     63164570 :   switch (stmt ? gimple_code (stmt) : GIMPLE_ERROR_MARK)
    6196              :     {
    6197              :     case GIMPLE_COND:
    6198              :       /* For COND_EXPR, we only need to redirect the edge.  */
    6199              :       break;
    6200              : 
    6201            0 :     case GIMPLE_GOTO:
    6202              :       /* No non-abnormal edges should lead from a non-simple goto, and
    6203              :          simple ones should be represented implicitly.  */
    6204            0 :       gcc_unreachable ();
    6205              : 
    6206       376830 :     case GIMPLE_SWITCH:
    6207       376830 :       {
    6208       376830 :         gswitch *switch_stmt = as_a <gswitch *> (stmt);
    6209       376830 :         tree label = gimple_block_label (dest);
    6210       376830 :         tree cases = get_cases_for_edge (e, switch_stmt);
    6211              : 
    6212              :         /* If we have a list of cases associated with E, then use it
    6213              :            as it's a lot faster than walking the entire case vector.  */
    6214       376830 :         if (cases)
    6215              :           {
    6216       326006 :             edge e2 = find_edge (e->src, dest);
    6217       326006 :             tree last, first;
    6218              : 
    6219       326006 :             first = cases;
    6220      1041743 :             while (cases)
    6221              :               {
    6222       389731 :                 last = cases;
    6223       389731 :                 CASE_LABEL (cases) = label;
    6224       389731 :                 cases = CASE_CHAIN (cases);
    6225              :               }
    6226              : 
    6227              :             /* If there was already an edge in the CFG, then we need
    6228              :                to move all the cases associated with E to E2.  */
    6229       326006 :             if (e2)
    6230              :               {
    6231         8629 :                 tree cases2 = get_cases_for_edge (e2, switch_stmt);
    6232              : 
    6233         8629 :                 CASE_CHAIN (last) = CASE_CHAIN (cases2);
    6234         8629 :                 CASE_CHAIN (cases2) = first;
    6235              :               }
    6236       326006 :             bitmap_set_bit (touched_switch_bbs, gimple_bb (stmt)->index);
    6237              :           }
    6238              :         else
    6239              :           {
    6240        50824 :             size_t i, n = gimple_switch_num_labels (switch_stmt);
    6241              : 
    6242      4696122 :             for (i = 0; i < n; i++)
    6243              :               {
    6244      4645298 :                 tree elt = gimple_switch_label (switch_stmt, i);
    6245      4645298 :                 if (label_to_block (cfun, CASE_LABEL (elt)) == e->dest)
    6246        58096 :                   CASE_LABEL (elt) = label;
    6247              :               }
    6248              :           }
    6249              :       }
    6250              :       break;
    6251              : 
    6252        10563 :     case GIMPLE_ASM:
    6253        10563 :       {
    6254        10563 :         gasm *asm_stmt = as_a <gasm *> (stmt);
    6255        10563 :         int i, n = gimple_asm_nlabels (asm_stmt);
    6256        10563 :         tree label = NULL;
    6257              : 
    6258        15239 :         for (i = 0; i < n; ++i)
    6259              :           {
    6260         4676 :             tree cons = gimple_asm_label_op (asm_stmt, i);
    6261         4676 :             if (label_to_block (cfun, TREE_VALUE (cons)) == e->dest)
    6262              :               {
    6263         2299 :                 if (!label)
    6264         2299 :                   label = gimple_block_label (dest);
    6265         2299 :                 TREE_VALUE (cons) = label;
    6266              :               }
    6267              :           }
    6268              : 
    6269              :         /* If we didn't find any label matching the former edge in the
    6270              :            asm labels, we must be redirecting the fallthrough
    6271              :            edge.  */
    6272        10563 :         gcc_assert (label || (e->flags & EDGE_FALLTHRU));
    6273              :       }
    6274              :       break;
    6275              : 
    6276          254 :     case GIMPLE_RETURN:
    6277          254 :       gsi_remove (&gsi, true);
    6278          254 :       e->flags |= EDGE_FALLTHRU;
    6279          254 :       break;
    6280              : 
    6281              :     case GIMPLE_OMP_RETURN:
    6282              :     case GIMPLE_OMP_CONTINUE:
    6283              :     case GIMPLE_OMP_SECTIONS_SWITCH:
    6284              :     case GIMPLE_OMP_FOR:
    6285              :       /* The edges from OMP constructs can be simply redirected.  */
    6286              :       break;
    6287              : 
    6288            0 :     case GIMPLE_EH_DISPATCH:
    6289            0 :       if (!(e->flags & EDGE_FALLTHRU))
    6290            0 :         redirect_eh_dispatch_edge (as_a <geh_dispatch *> (stmt), e, dest);
    6291              :       break;
    6292              : 
    6293          346 :     case GIMPLE_TRANSACTION:
    6294          346 :       if (e->flags & EDGE_TM_ABORT)
    6295           81 :         gimple_transaction_set_label_over (as_a <gtransaction *> (stmt),
    6296              :                                            gimple_block_label (dest));
    6297          265 :       else if (e->flags & EDGE_TM_UNINSTRUMENTED)
    6298          128 :         gimple_transaction_set_label_uninst (as_a <gtransaction *> (stmt),
    6299              :                                              gimple_block_label (dest));
    6300              :       else
    6301          137 :         gimple_transaction_set_label_norm (as_a <gtransaction *> (stmt),
    6302              :                                            gimple_block_label (dest));
    6303              :       break;
    6304              : 
    6305      7746884 :     default:
    6306              :       /* Otherwise it must be a fallthru edge, and we don't need to
    6307              :          do anything besides redirecting it.  */
    6308      7746884 :       gcc_assert (e->flags & EDGE_FALLTHRU);
    6309              :       break;
    6310              :     }
    6311              : 
    6312              :   /* Update/insert PHI nodes as necessary.  */
    6313              : 
    6314              :   /* Now update the edges in the CFG.  */
    6315     63164570 :   e = ssa_redirect_edge (e, dest);
    6316              : 
    6317     63164570 :   return e;
    6318              : }
    6319              : 
    6320              : /* Returns true if it is possible to remove edge E by redirecting
    6321              :    it to the destination of the other edge from E->src.  */
    6322              : 
    6323              : static bool
    6324       304961 : gimple_can_remove_branch_p (const_edge e)
    6325              : {
    6326       304961 :   if (e->flags & (EDGE_ABNORMAL | EDGE_EH))
    6327            0 :     return false;
    6328              : 
    6329              :   return true;
    6330              : }
    6331              : 
    6332              : /* Simple wrapper, as we can always redirect fallthru edges.  */
    6333              : 
    6334              : static basic_block
    6335      3986928 : gimple_redirect_edge_and_branch_force (edge e, basic_block dest)
    6336              : {
    6337      3986928 :   e = gimple_redirect_edge_and_branch (e, dest);
    6338      3986928 :   gcc_assert (e);
    6339              : 
    6340      3986928 :   return NULL;
    6341              : }
    6342              : 
    6343              : 
    6344              : /* Splits basic block BB after statement STMT (but at least after the
    6345              :    labels).  If STMT is NULL, BB is split just after the labels.  */
    6346              : 
    6347              : static basic_block
    6348      5938567 : gimple_split_block (basic_block bb, void *stmt)
    6349              : {
    6350      5938567 :   gimple_stmt_iterator gsi;
    6351      5938567 :   gimple_stmt_iterator gsi_tgt;
    6352      5938567 :   gimple_seq list;
    6353      5938567 :   basic_block new_bb;
    6354      5938567 :   edge e;
    6355      5938567 :   edge_iterator ei;
    6356              : 
    6357      5938567 :   new_bb = create_empty_bb (bb);
    6358      5938567 :   if (coverage_suppressed_p (bb))
    6359          161 :     suppress_coverage (new_bb);
    6360              : 
    6361              :   /* Redirect the outgoing edges.  */
    6362      5938567 :   new_bb->succs = bb->succs;
    6363      5938567 :   bb->succs = NULL;
    6364     13689054 :   FOR_EACH_EDGE (e, ei, new_bb->succs)
    6365      7750487 :     e->src = new_bb;
    6366              : 
    6367              :   /* Get a stmt iterator pointing to the first stmt to move.  */
    6368      5938567 :   if (!stmt || gimple_code ((gimple *) stmt) == GIMPLE_LABEL)
    6369      1460209 :     gsi = gsi_after_labels (bb);
    6370              :   else
    6371              :     {
    6372      4478358 :       gsi = gsi_for_stmt ((gimple *) stmt);
    6373      4478358 :       gsi_next (&gsi);
    6374              :     }
    6375              : 
    6376              :   /* Move everything from GSI to the new basic block.  */
    6377      5938567 :   if (gsi_end_p (gsi))
    6378              :     return new_bb;
    6379              : 
    6380              :   /* Split the statement list - avoid re-creating new containers as this
    6381              :      brings ugly quadratic memory consumption in the inliner.
    6382              :      (We are still quadratic since we need to update stmt BB pointers,
    6383              :      sadly.)  */
    6384      5517196 :   gsi_split_seq_before (&gsi, &list);
    6385      5517196 :   set_bb_seq (new_bb, list);
    6386      5517196 :   for (gsi_tgt = gsi_start (list);
    6387     31464852 :        !gsi_end_p (gsi_tgt); gsi_next (&gsi_tgt))
    6388     25947656 :     gimple_set_bb (gsi_stmt (gsi_tgt), new_bb);
    6389              : 
    6390              :   return new_bb;
    6391              : }
    6392              : 
    6393              : 
    6394              : /* Moves basic block BB after block AFTER.  */
    6395              : 
    6396              : static bool
    6397     23961503 : gimple_move_block_after (basic_block bb, basic_block after)
    6398              : {
    6399     23961503 :   if (bb->prev_bb == after)
    6400              :     return true;
    6401              : 
    6402      5722958 :   unlink_block (bb);
    6403      5722958 :   link_block (bb, after);
    6404              : 
    6405      5722958 :   return true;
    6406              : }
    6407              : 
    6408              : 
    6409              : /* Return TRUE if block BB has no executable statements, otherwise return
    6410              :    FALSE.  */
    6411              : 
    6412              : static bool
    6413     15301687 : gimple_empty_block_p (basic_block bb)
    6414              : {
    6415              :   /* BB must have no executable statements.  */
    6416     15301687 :   gimple_stmt_iterator gsi = gsi_after_labels (bb);
    6417     15301687 :   if (phi_nodes (bb))
    6418              :     return false;
    6419     21476307 :   while (!gsi_end_p (gsi))
    6420              :     {
    6421     11517356 :       gimple *stmt = gsi_stmt (gsi);
    6422     11517356 :       if (is_gimple_debug (stmt))
    6423              :         ;
    6424      4207149 :       else if (gimple_code (stmt) == GIMPLE_NOP
    6425      4207149 :                || gimple_code (stmt) == GIMPLE_PREDICT)
    6426              :         ;
    6427              :       else
    6428              :         return false;
    6429      7350586 :       gsi_next (&gsi);
    6430              :     }
    6431              :   return true;
    6432              : }
    6433              : 
    6434              : 
    6435              : /* Split a basic block if it ends with a conditional branch and if the
    6436              :    other part of the block is not empty.  */
    6437              : 
    6438              : static basic_block
    6439          558 : gimple_split_block_before_cond_jump (basic_block bb)
    6440              : {
    6441          558 :   gimple *last, *split_point;
    6442          558 :   gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);
    6443          558 :   if (gsi_end_p (gsi))
    6444              :     return NULL;
    6445          558 :   last = gsi_stmt (gsi);
    6446          558 :   if (gimple_code (last) != GIMPLE_COND
    6447          558 :       && gimple_code (last) != GIMPLE_SWITCH)
    6448              :     return NULL;
    6449          558 :   gsi_prev (&gsi);
    6450          558 :   split_point = gsi_stmt (gsi);
    6451          558 :   return split_block (bb, split_point)->dest;
    6452              : }
    6453              : 
    6454              : 
    6455              : /* Return true if basic_block can be duplicated.  */
    6456              : 
    6457              : static bool
    6458      9963533 : gimple_can_duplicate_bb_p (const_basic_block bb)
    6459              : {
    6460      9963533 :   gimple *last = last_nondebug_stmt (const_cast<basic_block> (bb));
    6461              : 
    6462              :   /* Do checks that can only fail for the last stmt, to minimize the work in the
    6463              :      stmt loop.  */
    6464      9963533 :   if (last) {
    6465              :     /* A transaction is a single entry multiple exit region.  It
    6466              :        must be duplicated in its entirety or not at all.  */
    6467      8481763 :     if (gimple_code (last) == GIMPLE_TRANSACTION)
    6468              :       return false;
    6469              : 
    6470              :     /* An IFN_UNIQUE call must be duplicated as part of its group,
    6471              :        or not at all.  */
    6472      8481761 :     if (is_gimple_call (last)
    6473        71922 :         && gimple_call_internal_p (last)
    6474      8482224 :         && gimple_call_internal_unique_p (last))
    6475              :       return false;
    6476              : 
    6477              :     /* Prohibit duplication of returns_twice calls, otherwise associated
    6478              :        abnormal edges also need to be duplicated properly.
    6479              :        return_twice functions will always be the last statement.  */
    6480      8481761 :     if (is_gimple_call (last)
    6481      8481761 :         && (gimple_call_flags (last) & ECF_RETURNS_TWICE))
    6482              :       return false;
    6483              :   }
    6484              : 
    6485     19926642 :   for (gimple_stmt_iterator gsi = gsi_start_bb (const_cast<basic_block> (bb));
    6486     73645503 :        !gsi_end_p (gsi); gsi_next (&gsi))
    6487              :     {
    6488     63682182 :       gimple *g = gsi_stmt (gsi);
    6489              : 
    6490              :       /* An IFN_GOMP_SIMT_ENTER_ALLOC/IFN_GOMP_SIMT_EXIT call must be
    6491              :          duplicated as part of its group, or not at all.
    6492              :          The IFN_GOMP_SIMT_VOTE_ANY and IFN_GOMP_SIMT_XCHG_* are part of such a
    6493              :          group, so the same holds there.  */
    6494     63682182 :       if (is_gimple_call (g)
    6495     63682182 :           && (gimple_call_internal_p (g, IFN_GOMP_SIMT_ENTER_ALLOC)
    6496       478208 :               || gimple_call_internal_p (g, IFN_GOMP_SIMT_EXIT)
    6497       478208 :               || gimple_call_internal_p (g, IFN_GOMP_SIMT_VOTE_ANY)
    6498       478208 :               || gimple_call_internal_p (g, IFN_GOMP_SIMT_XCHG_BFLY)
    6499       478208 :               || gimple_call_internal_p (g, IFN_GOMP_SIMT_XCHG_IDX)))
    6500      9963533 :         return false;
    6501              :     }
    6502              : 
    6503              :   return true;
    6504              : }
    6505              : 
    6506              : /* Create a duplicate of the basic block BB.  NOTE: This does not
    6507              :    preserve SSA form.  */
    6508              : 
    6509              : static basic_block
    6510      4066801 : gimple_duplicate_bb (basic_block bb, copy_bb_data *id)
    6511              : {
    6512      4066801 :   basic_block new_bb;
    6513      4066801 :   gimple_stmt_iterator gsi_tgt;
    6514              : 
    6515      4066801 :   new_bb = create_empty_bb (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb);
    6516      4066801 :   if (coverage_suppressed_p (bb))
    6517            0 :     suppress_coverage (new_bb);
    6518              : 
    6519              :   /* Copy the PHI nodes.  We ignore PHI node arguments here because
    6520              :      the incoming edges have not been setup yet.  */
    6521      4066801 :   for (gphi_iterator gpi = gsi_start_phis (bb);
    6522      9557410 :        !gsi_end_p (gpi);
    6523      5490609 :        gsi_next (&gpi))
    6524              :     {
    6525      5490609 :       gphi *phi, *copy;
    6526      5490609 :       phi = gpi.phi ();
    6527      5490609 :       copy = create_phi_node (NULL_TREE, new_bb);
    6528      5490609 :       create_new_def_for (gimple_phi_result (phi), copy,
    6529              :                           gimple_phi_result_ptr (copy));
    6530      5490609 :       gimple_set_uid (copy, gimple_uid (phi));
    6531              :     }
    6532              : 
    6533      4066801 :   gsi_tgt = gsi_start_bb (new_bb);
    6534      8133602 :   for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
    6535     28893853 :        !gsi_end_p (gsi);
    6536     24827052 :        gsi_next (&gsi))
    6537              :     {
    6538     24827052 :       def_operand_p def_p;
    6539     24827052 :       ssa_op_iter op_iter;
    6540     24827052 :       tree lhs;
    6541     24827052 :       gimple *stmt, *copy;
    6542              : 
    6543     24827052 :       stmt = gsi_stmt (gsi);
    6544     24827052 :       if (gimple_code (stmt) == GIMPLE_LABEL)
    6545        92535 :         continue;
    6546              : 
    6547              :       /* Don't duplicate label debug stmts.  */
    6548     24736945 :       if (gimple_debug_bind_p (stmt)
    6549     15785824 :           && TREE_CODE (gimple_debug_bind_get_var (stmt))
    6550              :              == LABEL_DECL)
    6551         2428 :         continue;
    6552              : 
    6553              :       /* Create a new copy of STMT and duplicate STMT's virtual
    6554              :          operands.  */
    6555     24734517 :       copy = gimple_copy (stmt);
    6556     24734517 :       gsi_insert_after (&gsi_tgt, copy, GSI_NEW_STMT);
    6557              : 
    6558     24734517 :       maybe_duplicate_eh_stmt (copy, stmt);
    6559     24734517 :       gimple_duplicate_stmt_histograms (cfun, copy, cfun, stmt);
    6560              : 
    6561              :       /* When copying around a stmt writing into a local non-user
    6562              :          aggregate, make sure it won't share stack slot with other
    6563              :          vars.  */
    6564     24734517 :       lhs = gimple_get_lhs (stmt);
    6565     24734517 :       if (lhs && TREE_CODE (lhs) != SSA_NAME)
    6566              :         {
    6567       881697 :           tree base = get_base_address (lhs);
    6568       881697 :           if (base
    6569       881697 :               && (VAR_P (base) || TREE_CODE (base) == RESULT_DECL)
    6570       574522 :               && DECL_IGNORED_P (base)
    6571       215272 :               && !TREE_STATIC (base)
    6572       213934 :               && !DECL_EXTERNAL (base)
    6573      1095629 :               && (!VAR_P (base) || !DECL_HAS_VALUE_EXPR_P (base)))
    6574       213932 :             DECL_NONSHAREABLE (base) = 1;
    6575              :         }
    6576              : 
    6577              :       /* If requested remap dependence info of cliques brought in
    6578              :          via inlining.  */
    6579     24734517 :       if (id)
    6580     66162825 :         for (unsigned i = 0; i < gimple_num_ops (copy); ++i)
    6581              :           {
    6582     45636188 :             tree op = gimple_op (copy, i);
    6583     45636188 :             if (!op)
    6584     11879996 :               continue;
    6585     33756192 :             if (TREE_CODE (op) == ADDR_EXPR
    6586     32423318 :                 || TREE_CODE (op) == WITH_SIZE_EXPR)
    6587      1332874 :               op = TREE_OPERAND (op, 0);
    6588     35926886 :             while (handled_component_p (op))
    6589      2170694 :               op = TREE_OPERAND (op, 0);
    6590     33756192 :             if ((TREE_CODE (op) == MEM_REF
    6591     33756192 :                  || TREE_CODE (op) == TARGET_MEM_REF)
    6592      1181944 :                 && MR_DEPENDENCE_CLIQUE (op) > 1
    6593     33833821 :                 && MR_DEPENDENCE_CLIQUE (op) != bb->loop_father->owned_clique)
    6594              :               {
    6595        30107 :                 if (!id->dependence_map)
    6596        15222 :                   id->dependence_map = new hash_map<dependence_hash,
    6597              :                                                     unsigned short>;
    6598        30107 :                 bool existed;
    6599        30107 :                 unsigned short &newc = id->dependence_map->get_or_insert
    6600        30107 :                     (MR_DEPENDENCE_CLIQUE (op), &existed);
    6601        30107 :                 if (!existed)
    6602              :                   {
    6603        20733 :                     gcc_assert (MR_DEPENDENCE_CLIQUE (op) <= cfun->last_clique);
    6604        41466 :                     newc = get_new_clique (cfun);
    6605              :                   }
    6606        30107 :                 MR_DEPENDENCE_CLIQUE (op) = newc;
    6607              :               }
    6608              :           }
    6609              : 
    6610              :       /* Create new names for all the definitions created by COPY and
    6611              :          add replacement mappings for each new name.  */
    6612     30430276 :       FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_ALL_DEFS)
    6613      5695759 :         create_new_def_for (DEF_FROM_PTR (def_p), copy, def_p);
    6614              :     }
    6615              : 
    6616      4066801 :   return new_bb;
    6617              : }
    6618              : 
    6619              : /* Adds phi node arguments for edge E_COPY after basic block duplication.  */
    6620              : 
    6621              : static void
    6622      5407174 : add_phi_args_after_copy_edge (edge e_copy)
    6623              : {
    6624      5407174 :   basic_block bb, bb_copy = e_copy->src, dest;
    6625      5407174 :   edge e;
    6626      5407174 :   edge_iterator ei;
    6627      5407174 :   gphi *phi, *phi_copy;
    6628      5407174 :   tree def;
    6629      5407174 :   gphi_iterator psi, psi_copy;
    6630              : 
    6631      5407174 :   if (gimple_seq_empty_p (phi_nodes (e_copy->dest)))
    6632      3443919 :     return;
    6633              : 
    6634      1963255 :   bb = bb_copy->flags & BB_DUPLICATED ? get_bb_original (bb_copy) : bb_copy;
    6635              : 
    6636      1963255 :   if (e_copy->dest->flags & BB_DUPLICATED)
    6637       813443 :     dest = get_bb_original (e_copy->dest);
    6638              :   else
    6639              :     dest = e_copy->dest;
    6640              : 
    6641      1963255 :   e = find_edge (bb, dest);
    6642      1963255 :   if (!e)
    6643              :     {
    6644              :       /* During loop unrolling the target of the latch edge is copied.
    6645              :          In this case we are not looking for edge to dest, but to
    6646              :          duplicated block whose original was dest.  */
    6647         1106 :       FOR_EACH_EDGE (e, ei, bb->succs)
    6648              :         {
    6649         1106 :           if ((e->dest->flags & BB_DUPLICATED)
    6650         1106 :               && get_bb_original (e->dest) == dest)
    6651              :             break;
    6652              :         }
    6653              : 
    6654         1106 :       gcc_assert (e != NULL);
    6655              :     }
    6656              : 
    6657      1963255 :   for (psi = gsi_start_phis (e->dest),
    6658      1963255 :        psi_copy = gsi_start_phis (e_copy->dest);
    6659      5800917 :        !gsi_end_p (psi);
    6660      3837662 :        gsi_next (&psi), gsi_next (&psi_copy))
    6661              :     {
    6662      3837662 :       phi = psi.phi ();
    6663      3837662 :       phi_copy = psi_copy.phi ();
    6664      3837662 :       def = PHI_ARG_DEF_FROM_EDGE (phi, e);
    6665      3837662 :       add_phi_arg (phi_copy, def, e_copy,
    6666              :                    gimple_phi_arg_location_from_edge (phi, e));
    6667              :     }
    6668              : }
    6669              : 
    6670              : 
    6671              : /* Basic block BB_COPY was created by code duplication.  Add phi node
    6672              :    arguments for edges going out of BB_COPY.  The blocks that were
    6673              :    duplicated have BB_DUPLICATED set.  */
    6674              : 
    6675              : void
    6676      3763980 : add_phi_args_after_copy_bb (basic_block bb_copy)
    6677              : {
    6678      3763980 :   edge e_copy;
    6679      3763980 :   edge_iterator ei;
    6680              : 
    6681      9171131 :   FOR_EACH_EDGE (e_copy, ei, bb_copy->succs)
    6682              :     {
    6683      5407151 :       add_phi_args_after_copy_edge (e_copy);
    6684              :     }
    6685      3763980 : }
    6686              : 
    6687              : /* Blocks in REGION_COPY array of length N_REGION were created by
    6688              :    duplication of basic blocks.  Add phi node arguments for edges
    6689              :    going from these blocks.  If E_COPY is not NULL, also add
    6690              :    phi node arguments for its destination.*/
    6691              : 
    6692              : void
    6693      1968815 : add_phi_args_after_copy (basic_block *region_copy, unsigned n_region,
    6694              :                          edge e_copy)
    6695              : {
    6696      1968815 :   unsigned i;
    6697              : 
    6698      4515030 :   for (i = 0; i < n_region; i++)
    6699      2546215 :     region_copy[i]->flags |= BB_DUPLICATED;
    6700              : 
    6701      4515030 :   for (i = 0; i < n_region; i++)
    6702      2546215 :     add_phi_args_after_copy_bb (region_copy[i]);
    6703      1968815 :   if (e_copy)
    6704           23 :     add_phi_args_after_copy_edge (e_copy);
    6705              : 
    6706      4515030 :   for (i = 0; i < n_region; i++)
    6707      2546215 :     region_copy[i]->flags &= ~BB_DUPLICATED;
    6708      1968815 : }
    6709              : 
    6710              : /* Duplicates a REGION (set of N_REGION basic blocks) with just a single
    6711              :    important exit edge EXIT.  By important we mean that no SSA name defined
    6712              :    inside region is live over the other exit edges of the region.  All entry
    6713              :    edges to the region must go to ENTRY->dest.  The edge ENTRY is redirected
    6714              :    to the duplicate of the region.  Dominance and loop information is
    6715              :    updated if UPDATE_DOMINANCE is true, but not the SSA web.  If
    6716              :    UPDATE_DOMINANCE is false then we assume that the caller will update the
    6717              :    dominance information after calling this function.  The new basic
    6718              :    blocks are stored to REGION_COPY in the same order as they had in REGION,
    6719              :    provided that REGION_COPY is not NULL.
    6720              :    The function returns false if it is unable to copy the region,
    6721              :    true otherwise.
    6722              : 
    6723              :    It is callers responsibility to update profile.  */
    6724              : 
    6725              : bool
    6726       575844 : gimple_duplicate_seme_region (edge entry, edge exit,
    6727              :                               basic_block *region, unsigned n_region,
    6728              :                               basic_block *region_copy,
    6729              :                               bool update_dominance)
    6730              : {
    6731       575844 :   unsigned i;
    6732       575844 :   bool free_region_copy = false, copying_header = false;
    6733       575844 :   class loop *loop = entry->dest->loop_father;
    6734       575844 :   edge exit_copy;
    6735       575844 :   edge redirected;
    6736              : 
    6737       575844 :   if (!can_copy_bbs_p (region, n_region))
    6738              :     return false;
    6739              : 
    6740              :   /* Some sanity checking.  Note that we do not check for all possible
    6741              :      missuses of the functions.  I.e. if you ask to copy something weird,
    6742              :      it will work, but the state of structures probably will not be
    6743              :      correct.  */
    6744      1161210 :   for (i = 0; i < n_region; i++)
    6745              :     {
    6746              :       /* We do not handle subloops, i.e. all the blocks must belong to the
    6747              :          same loop.  */
    6748       585366 :       if (region[i]->loop_father != loop)
    6749              :         return false;
    6750              : 
    6751       585366 :       if (region[i] != entry->dest
    6752         9522 :           && region[i] == loop->header)
    6753              :         return false;
    6754              :     }
    6755              : 
    6756              :   /* In case the function is used for loop header copying (which is the primary
    6757              :      use), ensure that EXIT and its copy will be new latch and entry edges.  */
    6758       575844 :   if (loop->header == entry->dest)
    6759              :     {
    6760       575844 :       copying_header = true;
    6761              : 
    6762       575844 :       if (!dominated_by_p (CDI_DOMINATORS, loop->latch, exit->src))
    6763              :         return false;
    6764              : 
    6765      1161210 :       for (i = 0; i < n_region; i++)
    6766       585366 :         if (region[i] != exit->src
    6767       585366 :             && dominated_by_p (CDI_DOMINATORS, region[i], exit->src))
    6768              :           return false;
    6769              :     }
    6770              : 
    6771       575844 :   initialize_original_copy_tables ();
    6772              : 
    6773       575844 :   if (copying_header)
    6774       575844 :     set_loop_copy (loop, loop_outer (loop));
    6775              :   else
    6776            0 :     set_loop_copy (loop, loop);
    6777              : 
    6778       575844 :   if (!region_copy)
    6779              :     {
    6780            0 :       region_copy = XNEWVEC (basic_block, n_region);
    6781            0 :       free_region_copy = true;
    6782              :     }
    6783              : 
    6784              :   /* Record blocks outside the region that are dominated by something
    6785              :      inside.  */
    6786       575844 :   auto_vec<basic_block> doms;
    6787       575844 :   if (update_dominance)
    6788       575844 :     doms = get_dominated_by_region (CDI_DOMINATORS, region, n_region);
    6789              : 
    6790       575844 :   copy_bbs (region, n_region, region_copy, &exit, 1, &exit_copy, loop,
    6791              :             split_edge_bb_loc (entry), update_dominance);
    6792              : 
    6793       575844 :   if (copying_header)
    6794              :     {
    6795       575844 :       loop->header = exit->dest;
    6796       575844 :       loop->latch = exit->src;
    6797              :     }
    6798              : 
    6799              :   /* Redirect the entry and add the phi node arguments.  */
    6800       575844 :   redirected = redirect_edge_and_branch (entry, get_bb_copy (entry->dest));
    6801       575844 :   gcc_assert (redirected != NULL);
    6802       575844 :   flush_pending_stmts (entry);
    6803              : 
    6804              :   /* Concerning updating of dominators:  We must recount dominators
    6805              :      for entry block and its copy.  Anything that is outside of the
    6806              :      region, but was dominated by something inside needs recounting as
    6807              :      well.  */
    6808       575844 :   if (update_dominance)
    6809              :     {
    6810       575844 :       set_immediate_dominator (CDI_DOMINATORS, entry->dest, entry->src);
    6811       575844 :       doms.safe_push (get_bb_original (entry->dest));
    6812       575844 :       iterate_fix_dominators (CDI_DOMINATORS, doms, false);
    6813              :     }
    6814              : 
    6815              :   /* Add the other PHI node arguments.  */
    6816       575844 :   add_phi_args_after_copy (region_copy, n_region, NULL);
    6817              : 
    6818       575844 :   if (free_region_copy)
    6819            0 :     free (region_copy);
    6820              : 
    6821       575844 :   free_original_copy_tables ();
    6822       575844 :   return true;
    6823       575844 : }
    6824              : 
    6825              : /* Checks if BB is part of the region defined by N_REGION BBS.  */
    6826              : static bool
    6827            0 : bb_part_of_region_p (basic_block bb, basic_block* bbs, unsigned n_region)
    6828              : {
    6829            0 :   unsigned int n;
    6830              : 
    6831            0 :   for (n = 0; n < n_region; n++)
    6832              :     {
    6833            0 :      if (bb == bbs[n])
    6834              :        return true;
    6835              :     }
    6836              :   return false;
    6837              : }
    6838              : 
    6839              : 
    6840              : /* For each PHI in BB, copy the argument associated with SRC_E to TGT_E.
    6841              :    Assuming the argument exists, just does not have a value.
    6842              :    If USE_MAP is true, then use the redirect edge var map of TGT_E
    6843              :    for the new arguments; clearing the map afterwards.  */
    6844              : 
    6845              : void
    6846     30955621 : copy_phi_arg_into_existing_phi (edge src_e, edge tgt_e, bool use_map)
    6847              : {
    6848     30955621 :   int src_idx = src_e->dest_idx;
    6849     30955621 :   int tgt_idx = tgt_e->dest_idx;
    6850              : 
    6851              :   /* Iterate over each PHI in e->dest.  */
    6852     30955621 :   for (gphi_iterator gsi = gsi_start_phis (src_e->dest),
    6853     30955621 :                            gsi2 = gsi_start_phis (tgt_e->dest);
    6854     78061668 :        !gsi_end_p (gsi);
    6855     47106047 :        gsi_next (&gsi), gsi_next (&gsi2))
    6856              :     {
    6857     47106047 :       gphi *src_phi = gsi.phi ();
    6858     47106047 :       gphi *dest_phi = gsi2.phi ();
    6859     47106047 :       tree val = gimple_phi_arg_def (src_phi, src_idx);
    6860     47106047 :       location_t locus = gimple_phi_arg_location (src_phi, src_idx);
    6861              : 
    6862     47106047 :       if (use_map && TREE_CODE (val) == SSA_NAME)
    6863              :         {
    6864              :           /* If DEF is one of the results of PHI nodes removed during
    6865              :              redirection, replace it with the PHI argument that used
    6866              :              to be on E.  */
    6867      5049153 :           vec<edge_var_map> *head = redirect_edge_var_map_vector (tgt_e);
    6868     10098306 :           size_t length = head ? head->length () : 0;
    6869      8805869 :           for (size_t i = 0; i < length; i++)
    6870              :             {
    6871      7169546 :               edge_var_map *vm = &(*head)[i];
    6872      7169546 :               tree old_arg = redirect_edge_var_map_result (vm);
    6873      7169546 :               tree new_arg = redirect_edge_var_map_def (vm);
    6874              : 
    6875      7169546 :               if (val == old_arg)
    6876              :                 {
    6877      3412830 :                   val = new_arg;
    6878      3412830 :                   location_t locus1 = redirect_edge_var_map_location (vm);
    6879              :                   /* Don't remove the location if we remap one does not have one.  */
    6880      3412830 :                   if (locus1 != UNKNOWN_LOCATION)
    6881       512273 :                     locus = locus1;
    6882              :                   break;
    6883              :                 }
    6884              :             }
    6885              :         }
    6886              : 
    6887     47106047 :       SET_PHI_ARG_DEF (dest_phi, tgt_idx, val);
    6888     47106047 :       gimple_phi_arg_set_location (dest_phi, tgt_idx, locus);
    6889              :     }
    6890     30955621 :   if (use_map)
    6891      2877589 :     redirect_edge_var_map_clear (tgt_e);
    6892     30955621 : }
    6893              : 
    6894              : /* Duplicates REGION consisting of N_REGION blocks.  The new blocks
    6895              :    are stored to REGION_COPY in the same order in that they appear
    6896              :    in REGION, if REGION_COPY is not NULL.  ENTRY is the entry to
    6897              :    the region, EXIT an exit from it.  The condition guarding EXIT
    6898              :    is moved to ENTRY.  Returns true if duplication succeeds, false
    6899              :    otherwise.
    6900              : 
    6901              :    For example,
    6902              : 
    6903              :    some_code;
    6904              :    if (cond)
    6905              :      A;
    6906              :    else
    6907              :      B;
    6908              : 
    6909              :    is transformed to
    6910              : 
    6911              :    if (cond)
    6912              :      {
    6913              :        some_code;
    6914              :        A;
    6915              :      }
    6916              :    else
    6917              :      {
    6918              :        some_code;
    6919              :        B;
    6920              :      }
    6921              : */
    6922              : 
    6923              : bool
    6924           23 : gimple_duplicate_sese_tail (edge entry, edge exit,
    6925              :                           basic_block *region, unsigned n_region,
    6926              :                           basic_block *region_copy)
    6927              : {
    6928           23 :   unsigned i;
    6929           23 :   bool free_region_copy = false;
    6930           23 :   class loop *loop = exit->dest->loop_father;
    6931           23 :   class loop *orig_loop = entry->dest->loop_father;
    6932           23 :   basic_block switch_bb, entry_bb, nentry_bb;
    6933           23 :   profile_count total_count = profile_count::uninitialized (),
    6934           23 :                 exit_count = profile_count::uninitialized ();
    6935           23 :   edge exits[2], nexits[2], e;
    6936           23 :   gimple_stmt_iterator gsi;
    6937           23 :   edge sorig, snew;
    6938           23 :   basic_block exit_bb;
    6939           23 :   class loop *target, *aloop, *cloop;
    6940              : 
    6941           23 :   gcc_assert (EDGE_COUNT (exit->src->succs) == 2);
    6942           23 :   exits[0] = exit;
    6943           23 :   exits[1] = EDGE_SUCC (exit->src, EDGE_SUCC (exit->src, 0) == exit);
    6944              : 
    6945           23 :   if (!can_copy_bbs_p (region, n_region))
    6946              :     return false;
    6947              : 
    6948           23 :   initialize_original_copy_tables ();
    6949           23 :   set_loop_copy (orig_loop, loop);
    6950              : 
    6951           23 :   target= loop;
    6952           23 :   for (aloop = orig_loop->inner; aloop; aloop = aloop->next)
    6953              :     {
    6954            0 :       if (bb_part_of_region_p (aloop->header, region, n_region))
    6955              :         {
    6956            0 :           cloop = duplicate_loop (aloop, target);
    6957            0 :           duplicate_subloops (aloop, cloop);
    6958              :         }
    6959              :     }
    6960              : 
    6961           23 :   if (!region_copy)
    6962              :     {
    6963            0 :       region_copy = XNEWVEC (basic_block, n_region);
    6964            0 :       free_region_copy = true;
    6965              :     }
    6966              : 
    6967           23 :   gcc_assert (!need_ssa_update_p (cfun));
    6968              : 
    6969              :   /* Record blocks outside the region that are dominated by something
    6970              :      inside.  */
    6971           23 :   auto_vec<basic_block> doms = get_dominated_by_region (CDI_DOMINATORS, region,
    6972           23 :                                                         n_region);
    6973              : 
    6974           23 :   total_count = exit->src->count;
    6975           23 :   exit_count = exit->count ();
    6976              :   /* Fix up corner cases, to avoid division by zero or creation of negative
    6977              :      frequencies.  */
    6978           23 :   if (exit_count > total_count)
    6979            0 :     exit_count = total_count;
    6980              : 
    6981           23 :   copy_bbs (region, n_region, region_copy, exits, 2, nexits, orig_loop,
    6982              :             split_edge_bb_loc (exit), true);
    6983           23 :   if (total_count.initialized_p () && exit_count.initialized_p ())
    6984              :     {
    6985           23 :       scale_bbs_frequencies_profile_count (region, n_region,
    6986              :                                            total_count - exit_count,
    6987              :                                            total_count);
    6988           23 :       scale_bbs_frequencies_profile_count (region_copy, n_region, exit_count,
    6989              :                                            total_count);
    6990              :     }
    6991              : 
    6992              :   /* Create the switch block, and put the exit condition to it.  */
    6993           23 :   entry_bb = entry->dest;
    6994           23 :   nentry_bb = get_bb_copy (entry_bb);
    6995           23 :   if (!*gsi_last_bb (entry->src)
    6996           23 :       || !stmt_ends_bb_p (*gsi_last_bb (entry->src)))
    6997           23 :     switch_bb = entry->src;
    6998              :   else
    6999            0 :     switch_bb = split_edge (entry);
    7000           23 :   set_immediate_dominator (CDI_DOMINATORS, nentry_bb, switch_bb);
    7001              : 
    7002           46 :   gcond *cond_stmt = as_a <gcond *> (*gsi_last_bb (exit->src));
    7003           23 :   cond_stmt = as_a <gcond *> (gimple_copy (cond_stmt));
    7004              : 
    7005           23 :   gsi = gsi_last_bb (switch_bb);
    7006           23 :   gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
    7007              : 
    7008           23 :   sorig = single_succ_edge (switch_bb);
    7009           23 :   sorig->flags = exits[1]->flags;
    7010           23 :   sorig->probability = exits[1]->probability;
    7011           23 :   snew = make_edge (switch_bb, nentry_bb, exits[0]->flags);
    7012           23 :   snew->probability = exits[0]->probability;
    7013              : 
    7014              : 
    7015              :   /* Register the new edge from SWITCH_BB in loop exit lists.  */
    7016           23 :   rescan_loop_exit (snew, true, false);
    7017              : 
    7018              :   /* Add the PHI node arguments.  */
    7019           23 :   add_phi_args_after_copy (region_copy, n_region, snew);
    7020              : 
    7021              :   /* Get rid of now superfluous conditions and associated edges (and phi node
    7022              :      arguments).  */
    7023           23 :   exit_bb = exit->dest;
    7024              : 
    7025           23 :   e = redirect_edge_and_branch (exits[0], exits[1]->dest);
    7026           23 :   PENDING_STMT (e) = NULL;
    7027              : 
    7028              :   /* The latch of ORIG_LOOP was copied, and so was the backedge
    7029              :      to the original header.  We redirect this backedge to EXIT_BB.  */
    7030           48 :   for (i = 0; i < n_region; i++)
    7031           25 :     if (get_bb_original (region_copy[i]) == orig_loop->latch)
    7032              :       {
    7033            0 :         gcc_assert (single_succ_edge (region_copy[i]));
    7034            0 :         e = redirect_edge_and_branch (single_succ_edge (region_copy[i]), exit_bb);
    7035            0 :         PENDING_STMT (e) = NULL;
    7036            0 :         copy_phi_arg_into_existing_phi (nexits[0], e);
    7037              :       }
    7038           23 :   e = redirect_edge_and_branch (nexits[1], nexits[0]->dest);
    7039           23 :   PENDING_STMT (e) = NULL;
    7040              : 
    7041              :   /* Anything that is outside of the region, but was dominated by something
    7042              :      inside needs to update dominance info.  */
    7043           23 :   iterate_fix_dominators (CDI_DOMINATORS, doms, false);
    7044              : 
    7045           23 :   if (free_region_copy)
    7046            0 :     free (region_copy);
    7047              : 
    7048           23 :   free_original_copy_tables ();
    7049           23 :   return true;
    7050           23 : }
    7051              : 
    7052              : /* Add all the blocks dominated by ENTRY to the array BBS_P.  Stop
    7053              :    adding blocks when the dominator traversal reaches EXIT.  This
    7054              :    function silently assumes that ENTRY strictly dominates EXIT.  */
    7055              : 
    7056              : void
    7057       603095 : gather_blocks_in_sese_region (basic_block entry, basic_block exit,
    7058              :                               vec<basic_block> *bbs_p)
    7059              : {
    7060       603095 :   basic_block son;
    7061              : 
    7062       603095 :   for (son = first_dom_son (CDI_DOMINATORS, entry);
    7063      1206070 :        son;
    7064       602975 :        son = next_dom_son (CDI_DOMINATORS, son))
    7065              :     {
    7066       602975 :       bbs_p->safe_push (son);
    7067       602975 :       if (son != exit)
    7068       558736 :         gather_blocks_in_sese_region (son, exit, bbs_p);
    7069              :     }
    7070       603095 : }
    7071              : 
    7072              : /* Replaces *TP with a duplicate (belonging to function TO_CONTEXT).
    7073              :    The duplicates are recorded in VARS_MAP.  */
    7074              : 
    7075              : static void
    7076      4517089 : replace_by_duplicate_decl (tree *tp, hash_map<tree, tree> *vars_map,
    7077              :                            tree to_context)
    7078              : {
    7079      4517089 :   tree t = *tp, new_t;
    7080      4517089 :   struct function *f = DECL_STRUCT_FUNCTION (to_context);
    7081              : 
    7082      4517089 :   if (DECL_CONTEXT (t) == to_context)
    7083        35656 :     return;
    7084              : 
    7085      4481433 :   bool existed;
    7086      4481433 :   tree &loc = vars_map->get_or_insert (t, &existed);
    7087              : 
    7088      4481433 :   if (!existed)
    7089              :     {
    7090      1325454 :       if (SSA_VAR_P (t))
    7091              :         {
    7092      1314856 :           new_t = copy_var_decl (t, DECL_NAME (t), TREE_TYPE (t));
    7093      1314856 :           add_local_decl (f, new_t);
    7094              :         }
    7095              :       else
    7096              :         {
    7097        10598 :           gcc_assert (TREE_CODE (t) == CONST_DECL);
    7098        10598 :           new_t = copy_node (t);
    7099              :         }
    7100      1325454 :       DECL_CONTEXT (new_t) = to_context;
    7101              : 
    7102      1325454 :       loc = new_t;
    7103              :     }
    7104              :   else
    7105      3155979 :     new_t = loc;
    7106              : 
    7107      4481433 :   *tp = new_t;
    7108              : }
    7109              : 
    7110              : 
    7111              : /* Creates an ssa name in TO_CONTEXT equivalent to NAME.
    7112              :    VARS_MAP maps old ssa names and var_decls to the new ones.  */
    7113              : 
    7114              : static tree
    7115        14507 : replace_ssa_name (tree name, hash_map<tree, tree> *vars_map,
    7116              :                   tree to_context)
    7117              : {
    7118        14507 :   tree new_name;
    7119              : 
    7120        29014 :   gcc_assert (!virtual_operand_p (name));
    7121              : 
    7122        14507 :   tree *loc = vars_map->get (name);
    7123              : 
    7124        14507 :   if (!loc)
    7125              :     {
    7126         5994 :       tree decl = SSA_NAME_VAR (name);
    7127         5994 :       if (decl)
    7128              :         {
    7129         1199 :           gcc_assert (!SSA_NAME_IS_DEFAULT_DEF (name));
    7130         1199 :           replace_by_duplicate_decl (&decl, vars_map, to_context);
    7131         1199 :           new_name = make_ssa_name_fn (DECL_STRUCT_FUNCTION (to_context),
    7132         1199 :                                        decl, SSA_NAME_DEF_STMT (name));
    7133              :         }
    7134              :       else
    7135         4795 :         new_name = copy_ssa_name_fn (DECL_STRUCT_FUNCTION (to_context),
    7136         4795 :                                      name, SSA_NAME_DEF_STMT (name));
    7137              : 
    7138              :       /* Now that we've used the def stmt to define new_name, make sure it
    7139              :          doesn't define name anymore.  */
    7140         5994 :       SSA_NAME_DEF_STMT (name) = NULL;
    7141              : 
    7142         5994 :       vars_map->put (name, new_name);
    7143              :     }
    7144              :   else
    7145         8513 :     new_name = *loc;
    7146              : 
    7147        14507 :   return new_name;
    7148              : }
    7149              : 
    7150              : struct move_stmt_d
    7151              : {
    7152              :   tree orig_block;
    7153              :   tree new_block;
    7154              :   tree from_context;
    7155              :   tree to_context;
    7156              :   hash_map<tree, tree> *vars_map;
    7157              :   htab_t new_label_map;
    7158              :   hash_map<void *, void *> *eh_map;
    7159              :   bool remap_decls_p;
    7160              : };
    7161              : 
    7162              : /* Helper for move_block_to_fn.  Set TREE_BLOCK in every expression
    7163              :    contained in *TP if it has been ORIG_BLOCK previously and change the
    7164              :    DECL_CONTEXT of every local variable referenced in *TP.  */
    7165              : 
    7166              : static tree
    7167      7460336 : move_stmt_op (tree *tp, int *walk_subtrees, void *data)
    7168              : {
    7169      7460336 :   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
    7170      7460336 :   struct move_stmt_d *p = (struct move_stmt_d *) wi->info;
    7171      7460336 :   tree t = *tp;
    7172              : 
    7173      7460336 :   if (EXPR_P (t))
    7174              :     {
    7175      1183826 :       tree block = TREE_BLOCK (t);
    7176      1183826 :       if (block == NULL_TREE)
    7177              :         ;
    7178        30517 :       else if (block == p->orig_block
    7179        28533 :                || p->orig_block == NULL_TREE)
    7180              :         {
    7181              :           /* tree_node_can_be_shared says we can share invariant
    7182              :              addresses but unshare_expr copies them anyways.  Make sure
    7183              :              to unshare before adjusting the block in place - we do not
    7184              :              always see a copy here.  */
    7185         2008 :           if (TREE_CODE (t) == ADDR_EXPR
    7186         2008 :               && is_gimple_min_invariant (t))
    7187         1984 :             *tp = t = unshare_expr (t);
    7188         2008 :           TREE_SET_BLOCK (t, p->new_block);
    7189              :         }
    7190        28509 :       else if (flag_checking)
    7191              :         {
    7192       102956 :           while (block && TREE_CODE (block) == BLOCK && block != p->orig_block)
    7193        74447 :             block = BLOCK_SUPERCONTEXT (block);
    7194        28509 :           gcc_assert (block == p->orig_block);
    7195              :         }
    7196              :     }
    7197      6276510 :   else if (DECL_P (t) || TREE_CODE (t) == SSA_NAME)
    7198              :     {
    7199      4571815 :       if (TREE_CODE (t) == SSA_NAME)
    7200        12954 :         *tp = replace_ssa_name (t, p->vars_map, p->to_context);
    7201      4558861 :       else if (TREE_CODE (t) == PARM_DECL
    7202      4558861 :                && gimple_in_ssa_p (cfun))
    7203          183 :         *tp = *(p->vars_map->get (t));
    7204      4558678 :       else if (TREE_CODE (t) == LABEL_DECL)
    7205              :         {
    7206         2820 :           if (p->new_label_map)
    7207              :             {
    7208          479 :               struct tree_map in, *out;
    7209          479 :               in.base.from = t;
    7210          479 :               out = (struct tree_map *)
    7211          479 :                 htab_find_with_hash (p->new_label_map, &in, DECL_UID (t));
    7212          479 :               if (out)
    7213           13 :                 *tp = t = out->to;
    7214              :             }
    7215              : 
    7216              :           /* For FORCED_LABELs we can end up with references from other
    7217              :              functions if some SESE regions are outlined.  It is UB to
    7218              :              jump in between them, but they could be used just for printing
    7219              :              addresses etc.  In that case, DECL_CONTEXT on the label should
    7220              :              be the function containing the glabel stmt with that LABEL_DECL,
    7221              :              rather than whatever function a reference to the label was seen
    7222              :              last time.  */
    7223         2820 :           if (!FORCED_LABEL (t) && !DECL_NONLOCAL (t))
    7224         2813 :             DECL_CONTEXT (t) = p->to_context;
    7225              :         }
    7226      4555858 :       else if (p->remap_decls_p)
    7227              :         {
    7228              :           /* Replace T with its duplicate.  T should no longer appear in the
    7229              :              parent function, so this looks wasteful; however, it may appear
    7230              :              in referenced_vars, and more importantly, as virtual operands of
    7231              :              statements, and in alias lists of other variables.  It would be
    7232              :              quite difficult to expunge it from all those places.  ??? It might
    7233              :              suffice to do this for addressable variables.  */
    7234      3834433 :           if ((VAR_P (t) && !is_global_var (t))
    7235      4596543 :               || TREE_CODE (t) == CONST_DECL)
    7236      3804140 :             replace_by_duplicate_decl (tp, p->vars_map, p->to_context);
    7237              :         }
    7238      4571815 :       *walk_subtrees = 0;
    7239      4571815 :     }
    7240      1704695 :   else if (TYPE_P (t))
    7241            0 :     *walk_subtrees = 0;
    7242              : 
    7243      7460336 :   return NULL_TREE;
    7244              : }
    7245              : 
    7246              : /* Helper for move_stmt_r.  Given an EH region number for the source
    7247              :    function, map that to the duplicate EH region number in the dest.  */
    7248              : 
    7249              : static int
    7250           18 : move_stmt_eh_region_nr (int old_nr, struct move_stmt_d *p)
    7251              : {
    7252           18 :   eh_region old_r, new_r;
    7253              : 
    7254           18 :   old_r = get_eh_region_from_number (old_nr);
    7255           18 :   new_r = static_cast<eh_region> (*p->eh_map->get (old_r));
    7256              : 
    7257           18 :   return new_r->index;
    7258              : }
    7259              : 
    7260              : /* Similar, but operate on INTEGER_CSTs.  */
    7261              : 
    7262              : static tree
    7263            5 : move_stmt_eh_region_tree_nr (tree old_t_nr, struct move_stmt_d *p)
    7264              : {
    7265            5 :   int old_nr, new_nr;
    7266              : 
    7267            5 :   old_nr = tree_to_shwi (old_t_nr);
    7268            5 :   new_nr = move_stmt_eh_region_nr (old_nr, p);
    7269              : 
    7270            5 :   return build_int_cst (integer_type_node, new_nr);
    7271              : }
    7272              : 
    7273              : /* Like move_stmt_op, but for gimple statements.
    7274              : 
    7275              :    Helper for move_block_to_fn.  Set GIMPLE_BLOCK in every expression
    7276              :    contained in the current statement in *GSI_P and change the
    7277              :    DECL_CONTEXT of every local variable referenced in the current
    7278              :    statement.  */
    7279              : 
    7280              : static tree
    7281      2092715 : move_stmt_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
    7282              :              struct walk_stmt_info *wi)
    7283              : {
    7284      2092715 :   struct move_stmt_d *p = (struct move_stmt_d *) wi->info;
    7285      2092715 :   gimple *stmt = gsi_stmt (*gsi_p);
    7286      2092715 :   tree block = gimple_block (stmt);
    7287              : 
    7288      2092715 :   if (block == p->orig_block
    7289      1859789 :       || (p->orig_block == NULL_TREE
    7290          959 :           && block != NULL_TREE))
    7291       233885 :     gimple_set_block (stmt, p->new_block);
    7292              : 
    7293      2092715 :   switch (gimple_code (stmt))
    7294              :     {
    7295       276650 :     case GIMPLE_CALL:
    7296              :       /* Remap the region numbers for __builtin_eh_{pointer,filter}.  */
    7297       276650 :       {
    7298       276650 :         tree r, fndecl = gimple_call_fndecl (stmt);
    7299       276650 :         if (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
    7300        81576 :           switch (DECL_FUNCTION_CODE (fndecl))
    7301              :             {
    7302            0 :             case BUILT_IN_EH_COPY_VALUES:
    7303            0 :               r = gimple_call_arg (stmt, 1);
    7304            0 :               r = move_stmt_eh_region_tree_nr (r, p);
    7305            0 :               gimple_call_set_arg (stmt, 1, r);
    7306              :               /* FALLTHRU */
    7307              : 
    7308            5 :             case BUILT_IN_EH_POINTER:
    7309            5 :             case BUILT_IN_EH_FILTER:
    7310            5 :               r = gimple_call_arg (stmt, 0);
    7311            5 :               r = move_stmt_eh_region_tree_nr (r, p);
    7312            5 :               gimple_call_set_arg (stmt, 0, r);
    7313            5 :               break;
    7314              : 
    7315              :             default:
    7316              :               break;
    7317              :             }
    7318              :       }
    7319              :       break;
    7320              : 
    7321            8 :     case GIMPLE_RESX:
    7322            8 :       {
    7323            8 :         gresx *resx_stmt = as_a <gresx *> (stmt);
    7324            8 :         int r = gimple_resx_region (resx_stmt);
    7325            8 :         r = move_stmt_eh_region_nr (r, p);
    7326            8 :         gimple_resx_set_region (resx_stmt, r);
    7327              :       }
    7328            8 :       break;
    7329              : 
    7330            5 :     case GIMPLE_EH_DISPATCH:
    7331            5 :       {
    7332            5 :         geh_dispatch *eh_dispatch_stmt = as_a <geh_dispatch *> (stmt);
    7333            5 :         int r = gimple_eh_dispatch_region (eh_dispatch_stmt);
    7334            5 :         r = move_stmt_eh_region_nr (r, p);
    7335            5 :         gimple_eh_dispatch_set_region (eh_dispatch_stmt, r);
    7336              :       }
    7337            5 :       break;
    7338              : 
    7339              :     case GIMPLE_OMP_RETURN:
    7340              :     case GIMPLE_OMP_CONTINUE:
    7341              :       break;
    7342              : 
    7343         1418 :     case GIMPLE_LABEL:
    7344         1418 :       {
    7345              :         /* For FORCED_LABEL, move_stmt_op doesn't adjust DECL_CONTEXT,
    7346              :            so that such labels can be referenced from other regions.
    7347              :            Make sure to update it when seeing a GIMPLE_LABEL though,
    7348              :            that is the owner of the label.  */
    7349         1418 :         walk_gimple_op (stmt, move_stmt_op, wi);
    7350         1418 :         *handled_ops_p = true;
    7351         1418 :         tree label = gimple_label_label (as_a <glabel *> (stmt));
    7352         1418 :         if (FORCED_LABEL (label) || DECL_NONLOCAL (label))
    7353            5 :           DECL_CONTEXT (label) = p->to_context;
    7354              :       }
    7355              :       break;
    7356              : 
    7357      1814634 :     default:
    7358      1814634 :       if (is_gimple_omp (stmt))
    7359              :         {
    7360              :           /* Do not remap variables inside OMP directives.  Variables
    7361              :              referenced in clauses and directive header belong to the
    7362              :              parent function and should not be moved into the child
    7363              :              function.  */
    7364            0 :           bool save_remap_decls_p = p->remap_decls_p;
    7365            0 :           p->remap_decls_p = false;
    7366            0 :           *handled_ops_p = true;
    7367              : 
    7368            0 :           walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), move_stmt_r,
    7369              :                                move_stmt_op, wi);
    7370              : 
    7371            0 :           p->remap_decls_p = save_remap_decls_p;
    7372              :         }
    7373              :       break;
    7374              :     }
    7375              : 
    7376      2092715 :   return NULL_TREE;
    7377              : }
    7378              : 
    7379              : /* Move basic block BB from function CFUN to function DEST_FN.  The
    7380              :    block is moved out of the original linked list and placed after
    7381              :    block AFTER in the new list.  Also, the block is removed from the
    7382              :    original array of blocks and placed in DEST_FN's array of blocks.
    7383              :    If UPDATE_EDGE_COUNT_P is true, the edge counts on both CFGs is
    7384              :    updated to reflect the moved edges.
    7385              : 
    7386              :    The local variables are remapped to new instances, VARS_MAP is used
    7387              :    to record the mapping.  */
    7388              : 
    7389              : static void
    7390       645148 : move_block_to_fn (struct function *dest_cfun, basic_block bb,
    7391              :                   basic_block after, bool update_edge_count_p,
    7392              :                   struct move_stmt_d *d)
    7393              : {
    7394       645148 :   struct control_flow_graph *cfg;
    7395       645148 :   edge_iterator ei;
    7396       645148 :   edge e;
    7397       645148 :   gimple_stmt_iterator si;
    7398       645148 :   unsigned old_len;
    7399              : 
    7400              :   /* Remove BB from dominance structures.  */
    7401       645148 :   delete_from_dominance_info (CDI_DOMINATORS, bb);
    7402              : 
    7403              :   /* Move BB from its current loop to the copy in the new function.  */
    7404       645148 :   if (current_loops)
    7405              :     {
    7406       645148 :       class loop *new_loop = (class loop *)bb->loop_father->aux;
    7407       645148 :       if (new_loop)
    7408       363637 :         bb->loop_father = new_loop;
    7409              :     }
    7410              : 
    7411              :   /* Link BB to the new linked list.  */
    7412       645148 :   move_block_after (bb, after);
    7413              : 
    7414              :   /* Update the edge count in the corresponding flowgraphs.  */
    7415       645148 :   if (update_edge_count_p)
    7416      1382253 :     FOR_EACH_EDGE (e, ei, bb->succs)
    7417              :       {
    7418       780954 :         cfun->cfg->x_n_edges--;
    7419       780954 :         dest_cfun->cfg->x_n_edges++;
    7420              :       }
    7421              : 
    7422              :   /* Remove BB from the original basic block array.  */
    7423       645148 :   (*cfun->cfg->x_basic_block_info)[bb->index] = NULL;
    7424       645148 :   cfun->cfg->x_n_basic_blocks--;
    7425              : 
    7426              :   /* Grow DEST_CFUN's basic block array if needed.  */
    7427       645148 :   cfg = dest_cfun->cfg;
    7428       645148 :   cfg->x_n_basic_blocks++;
    7429       645148 :   if (bb->index >= cfg->x_last_basic_block)
    7430        43969 :     cfg->x_last_basic_block = bb->index + 1;
    7431              : 
    7432       645148 :   old_len = vec_safe_length (cfg->x_basic_block_info);
    7433       645148 :   if ((unsigned) cfg->x_last_basic_block >= old_len)
    7434        35498 :     vec_safe_grow_cleared (cfg->x_basic_block_info,
    7435        35498 :                            cfg->x_last_basic_block + 1);
    7436              : 
    7437       645148 :   (*cfg->x_basic_block_info)[bb->index] = bb;
    7438              : 
    7439              :   /* Remap the variables in phi nodes.  */
    7440       645148 :   for (gphi_iterator psi = gsi_start_phis (bb);
    7441       646330 :        !gsi_end_p (psi); )
    7442              :     {
    7443         1182 :       gphi *phi = psi.phi ();
    7444         1182 :       use_operand_p use;
    7445         1182 :       tree op = PHI_RESULT (phi);
    7446         1182 :       ssa_op_iter oi;
    7447         1182 :       unsigned i;
    7448              : 
    7449         2364 :       if (virtual_operand_p (op))
    7450              :         {
    7451              :           /* Remove the phi nodes for virtual operands (alias analysis will be
    7452              :              run for the new function, anyway).  But replace all uses that
    7453              :              might be outside of the region we move.  */
    7454          534 :           use_operand_p use_p;
    7455          534 :           imm_use_iterator iter;
    7456          534 :           gimple *use_stmt;
    7457         1059 :           FOR_EACH_IMM_USE_STMT (use_stmt, iter, op)
    7458         1050 :             FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
    7459          525 :               SET_USE (use_p, SSA_NAME_VAR (op));
    7460          534 :           remove_phi_node (&psi, true);
    7461          534 :           continue;
    7462          534 :         }
    7463              : 
    7464          648 :       SET_PHI_RESULT (phi,
    7465              :                       replace_ssa_name (op, d->vars_map, dest_cfun->decl));
    7466         1706 :       FOR_EACH_PHI_ARG (use, phi, oi, SSA_OP_USE)
    7467              :         {
    7468         1058 :           op = USE_FROM_PTR (use);
    7469         1058 :           if (TREE_CODE (op) == SSA_NAME)
    7470          905 :             SET_USE (use, replace_ssa_name (op, d->vars_map, dest_cfun->decl));
    7471              :         }
    7472              : 
    7473         1706 :       for (i = 0; i < EDGE_COUNT (bb->preds); i++)
    7474              :         {
    7475         1058 :           location_t locus = gimple_phi_arg_location (phi, i);
    7476         1058 :           tree block = LOCATION_BLOCK (locus);
    7477              : 
    7478         1058 :           if (locus == UNKNOWN_LOCATION)
    7479          895 :             continue;
    7480          163 :           if (d->orig_block == NULL_TREE || block == d->orig_block)
    7481              :             {
    7482          163 :               locus = set_block (locus, d->new_block);
    7483          163 :               gimple_phi_arg_set_location (phi, i, locus);
    7484              :             }
    7485              :         }
    7486              : 
    7487          648 :       gsi_next (&psi);
    7488              :     }
    7489              : 
    7490      3383011 :   for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
    7491              :     {
    7492      2092715 :       gimple *stmt = gsi_stmt (si);
    7493      2092715 :       struct walk_stmt_info wi;
    7494              : 
    7495      2092715 :       memset (&wi, 0, sizeof (wi));
    7496      2092715 :       wi.info = d;
    7497      2092715 :       walk_gimple_stmt (&si, move_stmt_r, move_stmt_op, &wi);
    7498              : 
    7499      2092715 :       if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
    7500              :         {
    7501         1418 :           tree label = gimple_label_label (label_stmt);
    7502         1418 :           int uid = LABEL_DECL_UID (label);
    7503              : 
    7504         1418 :           gcc_assert (uid > -1);
    7505              : 
    7506         1418 :           old_len = vec_safe_length (cfg->x_label_to_block_map);
    7507         1418 :           if (old_len <= (unsigned) uid)
    7508          171 :             vec_safe_grow_cleared (cfg->x_label_to_block_map, uid + 1);
    7509              : 
    7510         1418 :           (*cfg->x_label_to_block_map)[uid] = bb;
    7511         1418 :           (*cfun->cfg->x_label_to_block_map)[uid] = NULL;
    7512              : 
    7513         1418 :           gcc_assert (DECL_CONTEXT (label) == dest_cfun->decl);
    7514              : 
    7515         1418 :           if (uid >= dest_cfun->cfg->last_label_uid)
    7516          320 :             dest_cfun->cfg->last_label_uid = uid + 1;
    7517              :         }
    7518              : 
    7519      2092715 :       maybe_duplicate_eh_stmt_fn (dest_cfun, stmt, cfun, stmt, d->eh_map, 0);
    7520      2092715 :       remove_stmt_from_eh_lp_fn (cfun, stmt);
    7521              : 
    7522      2092715 :       gimple_duplicate_stmt_histograms (dest_cfun, stmt, cfun, stmt);
    7523      2092715 :       gimple_remove_stmt_histograms (cfun, stmt);
    7524              : 
    7525              :       /* We cannot leave any operands allocated from the operand caches of
    7526              :          the current function.  */
    7527      2092715 :       free_stmt_operands (cfun, stmt);
    7528      2092715 :       push_cfun (dest_cfun);
    7529      2092715 :       update_stmt (stmt);
    7530      2092715 :       if (is_gimple_call (stmt))
    7531       276650 :         notice_special_calls (as_a <gcall *> (stmt));
    7532      2092715 :       pop_cfun ();
    7533              :     }
    7534              : 
    7535      1426102 :   FOR_EACH_EDGE (e, ei, bb->succs)
    7536       780954 :     if (e->goto_locus != UNKNOWN_LOCATION)
    7537              :       {
    7538        35571 :         tree block = LOCATION_BLOCK (e->goto_locus);
    7539        35571 :         if (d->orig_block == NULL_TREE
    7540        35569 :             || block == d->orig_block)
    7541         2611 :           e->goto_locus = set_block (e->goto_locus, d->new_block);
    7542              :       }
    7543       645148 : }
    7544              : 
    7545              : /* Examine the statements in BB (which is in SRC_CFUN); find and return
    7546              :    the outermost EH region.  Use REGION as the incoming base EH region.
    7547              :    If there is no single outermost region, return NULL and set *ALL to
    7548              :    true.  */
    7549              : 
    7550              : static eh_region
    7551       645143 : find_outermost_region_in_block (struct function *src_cfun,
    7552              :                                 basic_block bb, eh_region region,
    7553              :                                 bool *all)
    7554              : {
    7555       645143 :   gimple_stmt_iterator si;
    7556              : 
    7557      3382989 :   for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
    7558              :     {
    7559      2092704 :       gimple *stmt = gsi_stmt (si);
    7560      2092704 :       eh_region stmt_region;
    7561      2092704 :       int lp_nr;
    7562              : 
    7563      2092704 :       lp_nr = lookup_stmt_eh_lp_fn (src_cfun, stmt);
    7564      2092704 :       stmt_region = get_eh_region_from_lp_number_fn (src_cfun, lp_nr);
    7565      2092704 :       if (stmt_region)
    7566              :         {
    7567         3898 :           if (region == NULL)
    7568              :             region = stmt_region;
    7569         1846 :           else if (stmt_region != region)
    7570              :             {
    7571          249 :               region = eh_region_outermost (src_cfun, stmt_region, region);
    7572          249 :               if (region == NULL)
    7573              :                 {
    7574            1 :                   *all = true;
    7575            1 :                   return NULL;
    7576              :                 }
    7577              :             }
    7578              :         }
    7579              :     }
    7580              : 
    7581              :   return region;
    7582              : }
    7583              : 
    7584              : static tree
    7585           13 : new_label_mapper (tree decl, void *data)
    7586              : {
    7587           13 :   htab_t hash = (htab_t) data;
    7588           13 :   struct tree_map *m;
    7589           13 :   void **slot;
    7590              : 
    7591           13 :   gcc_assert (TREE_CODE (decl) == LABEL_DECL);
    7592              : 
    7593           13 :   m = XNEW (struct tree_map);
    7594           13 :   m->hash = DECL_UID (decl);
    7595           13 :   m->base.from = decl;
    7596           13 :   m->to = create_artificial_label (UNKNOWN_LOCATION);
    7597           13 :   LABEL_DECL_UID (m->to) = LABEL_DECL_UID (decl);
    7598           13 :   if (LABEL_DECL_UID (m->to) >= cfun->cfg->last_label_uid)
    7599            5 :     cfun->cfg->last_label_uid = LABEL_DECL_UID (m->to) + 1;
    7600              : 
    7601           13 :   slot = htab_find_slot_with_hash (hash, m, m->hash, INSERT);
    7602           13 :   gcc_assert (*slot == NULL);
    7603              : 
    7604           13 :   *slot = m;
    7605              : 
    7606           13 :   return m->to;
    7607              : }
    7608              : 
    7609              : /* Tree walker to replace the decls used inside value expressions by
    7610              :    duplicates.  */
    7611              : 
    7612              : static tree
    7613       266618 : replace_block_vars_by_duplicates_1 (tree *tp, int *walk_subtrees, void *data)
    7614              : {
    7615       266618 :   struct replace_decls_d *rd = (struct replace_decls_d *)data;
    7616              : 
    7617       266618 :   switch (TREE_CODE (*tp))
    7618              :     {
    7619        50634 :     case VAR_DECL:
    7620        50634 :     case PARM_DECL:
    7621        50634 :     case RESULT_DECL:
    7622        50634 :       replace_by_duplicate_decl (tp, rd->vars_map, rd->to_context);
    7623        50634 :       break;
    7624              :     default:
    7625              :       break;
    7626              :     }
    7627              : 
    7628       266618 :   if (IS_TYPE_OR_DECL_P (*tp))
    7629        86325 :     *walk_subtrees = false;
    7630              : 
    7631       266618 :   return NULL;
    7632              : }
    7633              : 
    7634              : /* Change DECL_CONTEXT of all BLOCK_VARS in block, including
    7635              :    subblocks.  */
    7636              : 
    7637              : static void
    7638       170907 : replace_block_vars_by_duplicates (tree block, hash_map<tree, tree> *vars_map,
    7639              :                                   tree to_context)
    7640              : {
    7641       170907 :   tree *tp, t;
    7642              : 
    7643       836860 :   for (tp = &BLOCK_VARS (block); *tp; tp = &DECL_CHAIN (*tp))
    7644              :     {
    7645       665953 :       t = *tp;
    7646       665953 :       if (!VAR_P (t) && TREE_CODE (t) != CONST_DECL)
    7647         7227 :         continue;
    7648       658726 :       replace_by_duplicate_decl (&t, vars_map, to_context);
    7649       658726 :       if (t != *tp)
    7650              :         {
    7651       658726 :           if (VAR_P (*tp) && DECL_HAS_VALUE_EXPR_P (*tp))
    7652              :             {
    7653        45757 :               tree x = DECL_VALUE_EXPR (*tp);
    7654        45757 :               struct replace_decls_d rd = { vars_map, to_context };
    7655        45757 :               unshare_expr (x);
    7656        45757 :               walk_tree (&x, replace_block_vars_by_duplicates_1, &rd, NULL);
    7657        45757 :               SET_DECL_VALUE_EXPR (t, x);
    7658        45757 :               DECL_HAS_VALUE_EXPR_P (t) = 1;
    7659              :             }
    7660       658726 :           DECL_CHAIN (t) = DECL_CHAIN (*tp);
    7661       658726 :           *tp = t;
    7662              :         }
    7663              :     }
    7664              : 
    7665       297845 :   for (block = BLOCK_SUBBLOCKS (block); block; block = BLOCK_CHAIN (block))
    7666       126938 :     replace_block_vars_by_duplicates (block, vars_map, to_context);
    7667       170907 : }
    7668              : 
    7669              : /* Fixup the loop arrays and numbers after moving LOOP and its subloops
    7670              :    from FN1 to FN2.  */
    7671              : 
    7672              : static void
    7673        71725 : fixup_loop_arrays_after_move (struct function *fn1, struct function *fn2,
    7674              :                               class loop *loop)
    7675              : {
    7676              :   /* Discard it from the old loop array.  */
    7677       143450 :   (*get_loops (fn1))[loop->num] = NULL;
    7678              : 
    7679              :   /* Place it in the new loop array, assigning it a new number.  */
    7680        71725 :   loop->num = number_of_loops (fn2);
    7681        71725 :   vec_safe_push (loops_for_fn (fn2)->larray, loop);
    7682              : 
    7683              :   /* Recurse to children.  */
    7684       102454 :   for (loop = loop->inner; loop; loop = loop->next)
    7685        30729 :     fixup_loop_arrays_after_move (fn1, fn2, loop);
    7686        71725 : }
    7687              : 
    7688              : /* Verify that the blocks in BBS_P are a single-entry, single-exit region
    7689              :    delimited by ENTRY_BB and EXIT_BB, possibly containing noreturn blocks.  */
    7690              : 
    7691              : DEBUG_FUNCTION void
    7692        43969 : verify_sese (basic_block entry, basic_block exit, vec<basic_block> *bbs_p)
    7693              : {
    7694        43969 :   basic_block bb;
    7695        43969 :   edge_iterator ei;
    7696        43969 :   edge e;
    7697        43969 :   bitmap bbs = BITMAP_ALLOC (NULL);
    7698        43969 :   int i;
    7699              : 
    7700        43969 :   gcc_assert (entry != NULL);
    7701        43969 :   gcc_assert (entry != exit);
    7702        43969 :   gcc_assert (bbs_p != NULL);
    7703              : 
    7704        43969 :   gcc_assert (bbs_p->length () > 0);
    7705              : 
    7706       689117 :   FOR_EACH_VEC_ELT (*bbs_p, i, bb)
    7707       645148 :     bitmap_set_bit (bbs, bb->index);
    7708              : 
    7709        43969 :   gcc_assert (bitmap_bit_p (bbs, entry->index));
    7710        43969 :   gcc_assert (exit == NULL || bitmap_bit_p (bbs, exit->index));
    7711              : 
    7712       689117 :   FOR_EACH_VEC_ELT (*bbs_p, i, bb)
    7713              :     {
    7714       645148 :       if (bb == entry)
    7715              :         {
    7716        43969 :           gcc_assert (single_pred_p (entry));
    7717        43969 :           gcc_assert (!bitmap_bit_p (bbs, single_pred (entry)->index));
    7718              :         }
    7719              :       else
    7720      1382133 :         for (ei = ei_start (bb->preds); !ei_end_p (ei); ei_next (&ei))
    7721              :           {
    7722       780954 :             e = ei_edge (ei);
    7723       780954 :             gcc_assert (bitmap_bit_p (bbs, e->src->index));
    7724              :           }
    7725              : 
    7726       645148 :       if (bb == exit)
    7727              :         {
    7728        43849 :           gcc_assert (single_succ_p (exit));
    7729        43849 :           gcc_assert (!bitmap_bit_p (bbs, single_succ (exit)->index));
    7730              :         }
    7731              :       else
    7732      1382253 :         for (ei = ei_start (bb->succs); !ei_end_p (ei); ei_next (&ei))
    7733              :           {
    7734       780954 :             e = ei_edge (ei);
    7735       780954 :             gcc_assert (bitmap_bit_p (bbs, e->dest->index));
    7736              :           }
    7737              :     }
    7738              : 
    7739        43969 :   BITMAP_FREE (bbs);
    7740        43969 : }
    7741              : 
    7742              : /* If FROM is an SSA_NAME, mark the version in bitmap DATA.  */
    7743              : 
    7744              : bool
    7745      1331643 : gather_ssa_name_hash_map_from (tree const &from, tree const &, void *data)
    7746              : {
    7747      1331643 :   bitmap release_names = (bitmap)data;
    7748              : 
    7749      1331643 :   if (TREE_CODE (from) != SSA_NAME)
    7750              :     return true;
    7751              : 
    7752         5994 :   bitmap_set_bit (release_names, SSA_NAME_VERSION (from));
    7753         5994 :   return true;
    7754              : }
    7755              : 
    7756              : /* Return LOOP_DIST_ALIAS call if present in BB.  */
    7757              : 
    7758              : static gimple *
    7759          113 : find_loop_dist_alias (basic_block bb)
    7760              : {
    7761          113 :   gimple_stmt_iterator gsi = gsi_last_bb (bb);
    7762          113 :   if (!safe_is_a <gcond *> (*gsi))
    7763              :     return NULL;
    7764              : 
    7765           30 :   gsi_prev (&gsi);
    7766           30 :   if (gsi_end_p (gsi))
    7767              :     return NULL;
    7768              : 
    7769           22 :   gimple *g = gsi_stmt (gsi);
    7770           22 :   if (gimple_call_internal_p (g, IFN_LOOP_DIST_ALIAS))
    7771            1 :     return g;
    7772              :   return NULL;
    7773              : }
    7774              : 
    7775              : /* Fold loop internal call G like IFN_LOOP_VECTORIZED/IFN_LOOP_DIST_ALIAS
    7776              :    to VALUE and update any immediate uses of it's LHS.  */
    7777              : 
    7778              : void
    7779        29430 : fold_loop_internal_call (gimple *g, tree value)
    7780              : {
    7781        29430 :   tree lhs = gimple_call_lhs (g);
    7782        29430 :   use_operand_p use_p;
    7783        29430 :   imm_use_iterator iter;
    7784        29430 :   gimple *use_stmt;
    7785        29430 :   gimple_stmt_iterator gsi = gsi_for_stmt (g);
    7786              : 
    7787        29430 :   replace_call_with_value (&gsi, value);
    7788        58766 :   FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
    7789              :     {
    7790        58672 :       FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
    7791        29336 :         SET_USE (use_p, value);
    7792        29336 :       update_stmt (use_stmt);
    7793              :       /* If we turn conditional to constant, scale profile counts.
    7794              :          We know that the conditional was created by loop distribution
    7795              :          and all basic blocks dominated by the taken edge are part of
    7796              :          the loop distributed.  */
    7797        29336 :       if (gimple_code (use_stmt) == GIMPLE_COND)
    7798              :         {
    7799        29336 :           edge true_edge, false_edge;
    7800        29336 :           extract_true_false_edges_from_block (gimple_bb (use_stmt),
    7801              :                                                &true_edge, &false_edge);
    7802        29336 :           edge taken_edge = NULL, other_edge = NULL;
    7803        29336 :           if (gimple_cond_true_p (as_a <gcond *>(use_stmt)))
    7804              :             {
    7805         7820 :               taken_edge = true_edge;
    7806         7820 :               other_edge = false_edge;
    7807              :             }
    7808        21516 :           else if (gimple_cond_false_p (as_a <gcond *>(use_stmt)))
    7809              :             {
    7810        21507 :               taken_edge = false_edge;
    7811        21507 :               other_edge = true_edge;
    7812              :             }
    7813        29327 :           if (taken_edge
    7814        29336 :               && !(taken_edge->probability == profile_probability::always ()))
    7815              :             {
    7816           30 :               profile_count old_count = taken_edge->count ();
    7817           30 :               profile_count new_count = taken_edge->src->count;
    7818           30 :               taken_edge->probability = profile_probability::always ();
    7819           30 :               other_edge->probability = profile_probability::never ();
    7820              :               /* If we have multiple predecessors, we can't use the dominance
    7821              :                  test.  This should not happen as the guarded code should
    7822              :                  start with pre-header.  */
    7823           30 :               gcc_assert (single_pred_edge (taken_edge->dest));
    7824           60 :               if (old_count.nonzero_p ())
    7825              :                 {
    7826           28 :                   taken_edge->dest->count
    7827           28 :                     = taken_edge->dest->count.apply_scale (new_count,
    7828              :                                                            old_count);
    7829           28 :                   scale_strictly_dominated_blocks (taken_edge->dest,
    7830              :                                                    new_count, old_count);
    7831              :                 }
    7832              :             }
    7833              :         }
    7834        29430 :     }
    7835        29430 : }
    7836              : 
    7837              : /* Move a single-entry, single-exit region delimited by ENTRY_BB and
    7838              :    EXIT_BB to function DEST_CFUN.  The whole region is replaced by a
    7839              :    single basic block in the original CFG and the new basic block is
    7840              :    returned.  DEST_CFUN must not have a CFG yet.
    7841              : 
    7842              :    Note that the region need not be a pure SESE region.  Blocks inside
    7843              :    the region may contain calls to abort/exit.  The only restriction
    7844              :    is that ENTRY_BB should be the only entry point and it must
    7845              :    dominate EXIT_BB.
    7846              : 
    7847              :    Change TREE_BLOCK of all statements in ORIG_BLOCK to the new
    7848              :    functions outermost BLOCK, move all subblocks of ORIG_BLOCK
    7849              :    to the new function.
    7850              : 
    7851              :    All local variables referenced in the region are assumed to be in
    7852              :    the corresponding BLOCK_VARS and unexpanded variable lists
    7853              :    associated with DEST_CFUN.
    7854              : 
    7855              :    TODO: investigate whether we can reuse gimple_duplicate_sese_region to
    7856              :    reimplement move_sese_region_to_fn by duplicating the region rather than
    7857              :    moving it.  */
    7858              : 
    7859              : basic_block
    7860        43969 : move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
    7861              :                         basic_block exit_bb, tree orig_block)
    7862              : {
    7863        43969 :   vec<basic_block> bbs;
    7864        43969 :   basic_block dom_entry = get_immediate_dominator (CDI_DOMINATORS, entry_bb);
    7865        43969 :   basic_block after, bb, *entry_pred, *exit_succ, abb;
    7866        43969 :   struct function *saved_cfun = cfun;
    7867        43969 :   int *entry_flag, *exit_flag;
    7868        43969 :   profile_probability *entry_prob, *exit_prob;
    7869        43969 :   unsigned i, num_entry_edges, num_exit_edges, num_nodes;
    7870        43969 :   edge e;
    7871        43969 :   edge_iterator ei;
    7872        43969 :   htab_t new_label_map;
    7873        43969 :   hash_map<void *, void *> *eh_map;
    7874        43969 :   class loop *loop = entry_bb->loop_father;
    7875        43969 :   class loop *loop0 = get_loop (saved_cfun, 0);
    7876        43969 :   struct move_stmt_d d;
    7877              : 
    7878              :   /* If ENTRY does not strictly dominate EXIT, this cannot be an SESE
    7879              :      region.  */
    7880        43969 :   gcc_assert (entry_bb != exit_bb
    7881              :               && (!exit_bb
    7882              :                   || dominated_by_p (CDI_DOMINATORS, exit_bb, entry_bb)));
    7883              : 
    7884              :   /* Collect all the blocks in the region.  Manually add ENTRY_BB
    7885              :      because it won't be added by dfs_enumerate_from.  */
    7886        43969 :   bbs.create (0);
    7887        43969 :   bbs.safe_push (entry_bb);
    7888        43969 :   gather_blocks_in_sese_region (entry_bb, exit_bb, &bbs);
    7889              : 
    7890        43969 :   if (flag_checking)
    7891        43969 :     verify_sese (entry_bb, exit_bb, &bbs);
    7892              : 
    7893              :   /* The blocks that used to be dominated by something in BBS will now be
    7894              :      dominated by the new block.  */
    7895        43969 :   auto_vec<basic_block> dom_bbs = get_dominated_by_region (CDI_DOMINATORS,
    7896              :                                                            bbs.address (),
    7897        87938 :                                                            bbs.length ());
    7898              : 
    7899              :   /* Detach ENTRY_BB and EXIT_BB from CFUN->CFG.  We need to remember
    7900              :      the predecessor edges to ENTRY_BB and the successor edges to
    7901              :      EXIT_BB so that we can re-attach them to the new basic block that
    7902              :      will replace the region.  */
    7903        43969 :   num_entry_edges = EDGE_COUNT (entry_bb->preds);
    7904        43969 :   entry_pred = XNEWVEC (basic_block, num_entry_edges);
    7905        43969 :   entry_flag = XNEWVEC (int, num_entry_edges);
    7906        43969 :   entry_prob = XNEWVEC (profile_probability, num_entry_edges);
    7907        43969 :   i = 0;
    7908        87938 :   for (ei = ei_start (entry_bb->preds); (e = ei_safe_edge (ei)) != NULL;)
    7909              :     {
    7910        43969 :       entry_prob[i] = e->probability;
    7911        43969 :       entry_flag[i] = e->flags;
    7912        43969 :       entry_pred[i++] = e->src;
    7913        43969 :       remove_edge (e);
    7914              :     }
    7915              : 
    7916        43969 :   if (exit_bb)
    7917              :     {
    7918        43849 :       num_exit_edges = EDGE_COUNT (exit_bb->succs);
    7919        43849 :       exit_succ = XNEWVEC (basic_block, num_exit_edges);
    7920        43849 :       exit_flag = XNEWVEC (int, num_exit_edges);
    7921        43849 :       exit_prob = XNEWVEC (profile_probability, num_exit_edges);
    7922        43849 :       i = 0;
    7923        87698 :       for (ei = ei_start (exit_bb->succs); (e = ei_safe_edge (ei)) != NULL;)
    7924              :         {
    7925        43849 :           exit_prob[i] = e->probability;
    7926        43849 :           exit_flag[i] = e->flags;
    7927        43849 :           exit_succ[i++] = e->dest;
    7928        43849 :           remove_edge (e);
    7929              :         }
    7930              :     }
    7931              :   else
    7932              :     {
    7933              :       num_exit_edges = 0;
    7934              :       exit_succ = NULL;
    7935              :       exit_flag = NULL;
    7936              :       exit_prob = NULL;
    7937              :     }
    7938              : 
    7939              :   /* Switch context to the child function to initialize DEST_FN's CFG.  */
    7940        43969 :   gcc_assert (dest_cfun->cfg == NULL);
    7941        43969 :   push_cfun (dest_cfun);
    7942              : 
    7943        43969 :   init_empty_tree_cfg ();
    7944              : 
    7945              :   /* Initialize EH information for the new function.  */
    7946        43969 :   eh_map = NULL;
    7947        43969 :   new_label_map = NULL;
    7948        43969 :   if (saved_cfun->eh)
    7949              :     {
    7950        43969 :       eh_region region = NULL;
    7951        43969 :       bool all = false;
    7952              : 
    7953       689111 :       FOR_EACH_VEC_ELT (bbs, i, bb)
    7954              :         {
    7955       645143 :           region = find_outermost_region_in_block (saved_cfun, bb, region, &all);
    7956       645143 :           if (all)
    7957              :             break;
    7958              :         }
    7959              : 
    7960        43969 :       init_eh_for_function ();
    7961        43969 :       if (region != NULL || all)
    7962              :         {
    7963         2052 :           new_label_map = htab_create (17, tree_map_hash, tree_map_eq, free);
    7964         2052 :           eh_map = duplicate_eh_regions (saved_cfun, region, 0,
    7965              :                                          new_label_mapper, new_label_map);
    7966              :         }
    7967              :     }
    7968              : 
    7969              :   /* Initialize an empty loop tree.  */
    7970        43969 :   struct loops *loops = ggc_cleared_alloc<struct loops> ();
    7971        43969 :   init_loops_structure (dest_cfun, loops, 1);
    7972        43969 :   loops->state = LOOPS_MAY_HAVE_MULTIPLE_LATCHES;
    7973        43969 :   set_loops_for_fn (dest_cfun, loops);
    7974              : 
    7975        87938 :   vec<loop_p, va_gc> *larray = get_loops (saved_cfun)->copy ();
    7976              : 
    7977              :   /* Move the outlined loop tree part.  */
    7978        43969 :   num_nodes = bbs.length ();
    7979       689117 :   FOR_EACH_VEC_ELT (bbs, i, bb)
    7980              :     {
    7981       645148 :       if (bb->loop_father->header == bb)
    7982              :         {
    7983        71725 :           class loop *this_loop = bb->loop_father;
    7984              :           /* Avoid the need to remap SSA names used in nb_iterations.  */
    7985        71725 :           free_numbers_of_iterations_estimates (this_loop);
    7986        71725 :           class loop *outer = loop_outer (this_loop);
    7987        71725 :           if (outer == loop
    7988              :               /* If the SESE region contains some bbs ending with
    7989              :                  a noreturn call, those are considered to belong
    7990              :                  to the outermost loop in saved_cfun, rather than
    7991              :                  the entry_bb's loop_father.  */
    7992        71725 :               || outer == loop0)
    7993              :             {
    7994        40996 :               if (outer != loop)
    7995            8 :                 num_nodes -= this_loop->num_nodes;
    7996        40996 :               flow_loop_tree_node_remove (bb->loop_father);
    7997        40996 :               flow_loop_tree_node_add (get_loop (dest_cfun, 0), this_loop);
    7998        40996 :               fixup_loop_arrays_after_move (saved_cfun, cfun, this_loop);
    7999              :             }
    8000              :         }
    8001       573423 :       else if (bb->loop_father == loop0 && loop0 != loop)
    8002         1264 :         num_nodes--;
    8003              : 
    8004              :       /* Remove loop exits from the outlined region.  */
    8005       645148 :       if (loops_for_fn (saved_cfun)->exits)
    8006         5658 :         FOR_EACH_EDGE (e, ei, bb->succs)
    8007              :           {
    8008         3071 :             struct loops *l = loops_for_fn (saved_cfun);
    8009         3071 :             loop_exit **slot
    8010         3071 :               = l->exits->find_slot_with_hash (e, htab_hash_pointer (e),
    8011              :                                                NO_INSERT);
    8012         3071 :             if (slot)
    8013          290 :               l->exits->clear_slot (slot);
    8014              :           }
    8015              :     }
    8016              : 
    8017              :   /* Adjust the number of blocks in the tree root of the outlined part.  */
    8018        87938 :   get_loop (dest_cfun, 0)->num_nodes = bbs.length () + 2;
    8019              : 
    8020              :   /* Setup a mapping to be used by move_block_to_fn.  */
    8021        43969 :   loop->aux = current_loops->tree_root;
    8022        43969 :   loop0->aux = current_loops->tree_root;
    8023              : 
    8024              :   /* Fix up orig_loop_num.  If the block referenced in it has been moved
    8025              :      to dest_cfun, update orig_loop_num field, otherwise clear it.  */
    8026        43969 :   signed char *moved_orig_loop_num = NULL;
    8027       203632 :   for (auto dloop : loops_list (dest_cfun, 0))
    8028        71725 :     if (dloop->orig_loop_num)
    8029              :       {
    8030            2 :         if (moved_orig_loop_num == NULL)
    8031            2 :           moved_orig_loop_num
    8032            2 :             = XCNEWVEC (signed char, vec_safe_length (larray));
    8033            2 :         if ((*larray)[dloop->orig_loop_num] != NULL
    8034            2 :             && get_loop (saved_cfun, dloop->orig_loop_num) == NULL)
    8035              :           {
    8036            0 :             if (moved_orig_loop_num[dloop->orig_loop_num] >= 0
    8037            0 :                 && moved_orig_loop_num[dloop->orig_loop_num] < 2)
    8038            0 :               moved_orig_loop_num[dloop->orig_loop_num]++;
    8039            0 :             dloop->orig_loop_num = (*larray)[dloop->orig_loop_num]->num;
    8040              :           }
    8041              :         else
    8042              :           {
    8043            2 :             moved_orig_loop_num[dloop->orig_loop_num] = -1;
    8044            2 :             dloop->orig_loop_num = 0;
    8045              :           }
    8046        43969 :       }
    8047        43969 :   pop_cfun ();
    8048              : 
    8049        43969 :   if (moved_orig_loop_num)
    8050              :     {
    8051           29 :       FOR_EACH_VEC_ELT (bbs, i, bb)
    8052              :         {
    8053           27 :           gimple *g = find_loop_dist_alias (bb);
    8054           27 :           if (g == NULL)
    8055           27 :             continue;
    8056              : 
    8057            0 :           int orig_loop_num = tree_to_shwi (gimple_call_arg (g, 0));
    8058            0 :           gcc_assert (orig_loop_num
    8059              :                       && (unsigned) orig_loop_num < vec_safe_length (larray));
    8060            0 :           if (moved_orig_loop_num[orig_loop_num] == 2)
    8061              :             {
    8062              :               /* If we have moved both loops with this orig_loop_num into
    8063              :                  dest_cfun and the LOOP_DIST_ALIAS call is being moved there
    8064              :                  too, update the first argument.  */
    8065            0 :               gcc_assert ((*larray)[orig_loop_num] != NULL
    8066              :                           && (get_loop (saved_cfun, orig_loop_num) == NULL));
    8067            0 :               tree t = build_int_cst (integer_type_node,
    8068            0 :                                       (*larray)[orig_loop_num]->num);
    8069            0 :               gimple_call_set_arg (g, 0, t);
    8070            0 :               update_stmt (g);
    8071              :               /* Make sure the following loop will not update it.  */
    8072            0 :               moved_orig_loop_num[orig_loop_num] = 0;
    8073              :             }
    8074              :           else
    8075              :             /* Otherwise at least one of the loops stayed in saved_cfun.
    8076              :                Remove the LOOP_DIST_ALIAS call.  */
    8077            0 :             fold_loop_internal_call (g, gimple_call_arg (g, 1));
    8078              :         }
    8079           88 :       FOR_EACH_BB_FN (bb, saved_cfun)
    8080              :         {
    8081           86 :           gimple *g = find_loop_dist_alias (bb);
    8082           86 :           if (g == NULL)
    8083           85 :             continue;
    8084            1 :           int orig_loop_num = tree_to_shwi (gimple_call_arg (g, 0));
    8085            2 :           gcc_assert (orig_loop_num
    8086              :                       && (unsigned) orig_loop_num < vec_safe_length (larray));
    8087            1 :           if (moved_orig_loop_num[orig_loop_num])
    8088              :             /* LOOP_DIST_ALIAS call remained in saved_cfun, if at least one
    8089              :                of the corresponding loops was moved, remove it.  */
    8090            1 :             fold_loop_internal_call (g, gimple_call_arg (g, 1));
    8091              :         }
    8092            2 :       XDELETEVEC (moved_orig_loop_num);
    8093              :     }
    8094        43969 :   ggc_free (larray);
    8095              : 
    8096              :   /* Move blocks from BBS into DEST_CFUN.  */
    8097        43969 :   gcc_assert (bbs.length () >= 2);
    8098        43969 :   after = dest_cfun->cfg->x_entry_block_ptr;
    8099        43969 :   hash_map<tree, tree> vars_map;
    8100              : 
    8101        43969 :   memset (&d, 0, sizeof (d));
    8102        43969 :   d.orig_block = orig_block;
    8103        43969 :   d.new_block = DECL_INITIAL (dest_cfun->decl);
    8104        43969 :   d.from_context = cfun->decl;
    8105        43969 :   d.to_context = dest_cfun->decl;
    8106        43969 :   d.vars_map = &vars_map;
    8107        43969 :   d.new_label_map = new_label_map;
    8108        43969 :   d.eh_map = eh_map;
    8109        43969 :   d.remap_decls_p = true;
    8110              : 
    8111        43969 :   if (gimple_in_ssa_p (cfun))
    8112          390 :     for (tree arg = DECL_ARGUMENTS (d.to_context); arg; arg = DECL_CHAIN (arg))
    8113              :       {
    8114          195 :         tree narg = make_ssa_name_fn (dest_cfun, arg, gimple_build_nop ());
    8115          195 :         set_ssa_default_def (dest_cfun, arg, narg);
    8116          195 :         vars_map.put (arg, narg);
    8117              :       }
    8118              : 
    8119       689117 :   FOR_EACH_VEC_ELT (bbs, i, bb)
    8120              :     {
    8121              :       /* No need to update edge counts on the last block.  It has
    8122              :          already been updated earlier when we detached the region from
    8123              :          the original CFG.  */
    8124       645148 :       move_block_to_fn (dest_cfun, bb, after, bb != exit_bb, &d);
    8125       645148 :       after = bb;
    8126              :     }
    8127              : 
    8128              :   /* Adjust the maximum clique used.  */
    8129        43969 :   dest_cfun->last_clique = saved_cfun->last_clique;
    8130              : 
    8131        43969 :   loop->aux = NULL;
    8132        43969 :   loop0->aux = NULL;
    8133              :   /* Loop sizes are no longer correct, fix them up.  */
    8134        43969 :   loop->num_nodes -= num_nodes;
    8135        43969 :   for (class loop *outer = loop_outer (loop);
    8136        48124 :        outer; outer = loop_outer (outer))
    8137         4155 :     outer->num_nodes -= num_nodes;
    8138        43969 :   loop0->num_nodes -= bbs.length () - num_nodes;
    8139              : 
    8140        43969 :   if (saved_cfun->has_simduid_loops || saved_cfun->has_force_vectorize_loops)
    8141              :     {
    8142         9294 :       class loop *aloop;
    8143        31211 :       for (i = 0; vec_safe_iterate (loops->larray, i, &aloop); i++)
    8144        21917 :         if (aloop != NULL)
    8145              :           {
    8146        21917 :             if (aloop->simduid)
    8147              :               {
    8148         2390 :                 replace_by_duplicate_decl (&aloop->simduid, d.vars_map,
    8149              :                                            d.to_context);
    8150         2390 :                 dest_cfun->has_simduid_loops = true;
    8151              :               }
    8152        21917 :             if (aloop->force_vectorize)
    8153         4236 :               dest_cfun->has_force_vectorize_loops = true;
    8154              :           }
    8155              :     }
    8156              : 
    8157              :   /* Rewire BLOCK_SUBBLOCKS of orig_block.  */
    8158        43969 :   if (orig_block)
    8159              :     {
    8160        43774 :       tree block;
    8161        43774 :       gcc_assert (BLOCK_SUBBLOCKS (DECL_INITIAL (dest_cfun->decl))
    8162              :                   == NULL_TREE);
    8163        87548 :       BLOCK_SUBBLOCKS (DECL_INITIAL (dest_cfun->decl))
    8164        43774 :         = BLOCK_SUBBLOCKS (orig_block);
    8165        43774 :       for (block = BLOCK_SUBBLOCKS (orig_block);
    8166        84075 :            block; block = BLOCK_CHAIN (block))
    8167        40301 :         BLOCK_SUPERCONTEXT (block) = DECL_INITIAL (dest_cfun->decl);
    8168        43774 :       BLOCK_SUBBLOCKS (orig_block) = NULL_TREE;
    8169              :     }
    8170              : 
    8171        43969 :   replace_block_vars_by_duplicates (DECL_INITIAL (dest_cfun->decl),
    8172              :                                     &vars_map, dest_cfun->decl);
    8173              : 
    8174        43969 :   if (new_label_map)
    8175         2052 :     htab_delete (new_label_map);
    8176        43969 :   if (eh_map)
    8177         2052 :     delete eh_map;
    8178              : 
    8179              :   /* We need to release ssa-names in a defined order, so first find them,
    8180              :      and then iterate in ascending version order.  */
    8181        43969 :   bitmap release_names = BITMAP_ALLOC (NULL);
    8182      1375612 :   vars_map.traverse<void *, gather_ssa_name_hash_map_from> (release_names);
    8183        43969 :   bitmap_iterator bi;
    8184        49963 :   EXECUTE_IF_SET_IN_BITMAP (release_names, 0, i, bi)
    8185         5994 :     release_ssa_name (ssa_name (i));
    8186        43969 :   BITMAP_FREE (release_names);
    8187              : 
    8188              :   /* Rewire the entry and exit blocks.  The successor to the entry
    8189              :      block turns into the successor of DEST_FN's ENTRY_BLOCK_PTR in
    8190              :      the child function.  Similarly, the predecessor of DEST_FN's
    8191              :      EXIT_BLOCK_PTR turns into the predecessor of EXIT_BLOCK_PTR.  We
    8192              :      need to switch CFUN between DEST_CFUN and SAVED_CFUN so that the
    8193              :      various CFG manipulation function get to the right CFG.
    8194              : 
    8195              :      FIXME, this is silly.  The CFG ought to become a parameter to
    8196              :      these helpers.  */
    8197        43969 :   push_cfun (dest_cfun);
    8198        43969 :   ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = entry_bb->count;
    8199        43969 :   make_single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), entry_bb, EDGE_FALLTHRU);
    8200        43969 :   if (exit_bb)
    8201              :     {
    8202        43849 :       make_single_succ_edge (exit_bb,  EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
    8203        43849 :       EXIT_BLOCK_PTR_FOR_FN (cfun)->count = exit_bb->count;
    8204              :     }
    8205              :   else
    8206          120 :     EXIT_BLOCK_PTR_FOR_FN (cfun)->count = profile_count::zero ();
    8207        43969 :   pop_cfun ();
    8208              : 
    8209              :   /* Back in the original function, the SESE region has disappeared,
    8210              :      create a new basic block in its place.  */
    8211        43969 :   bb = create_empty_bb (entry_pred[0]);
    8212        43969 :   if (current_loops)
    8213        43969 :     add_bb_to_loop (bb, loop);
    8214        43969 :   profile_count count = profile_count::zero ();
    8215        87938 :   for (i = 0; i < num_entry_edges; i++)
    8216              :     {
    8217        43969 :       e = make_edge (entry_pred[i], bb, entry_flag[i]);
    8218        43969 :       e->probability = entry_prob[i];
    8219        43969 :       count += e->count ();
    8220              :     }
    8221        43969 :   bb->count = count;
    8222              : 
    8223        87818 :   for (i = 0; i < num_exit_edges; i++)
    8224              :     {
    8225        43849 :       e = make_edge (bb, exit_succ[i], exit_flag[i]);
    8226        43849 :       e->probability = exit_prob[i];
    8227              :     }
    8228              : 
    8229        43969 :   set_immediate_dominator (CDI_DOMINATORS, bb, dom_entry);
    8230        83994 :   FOR_EACH_VEC_ELT (dom_bbs, i, abb)
    8231        40025 :     set_immediate_dominator (CDI_DOMINATORS, abb, bb);
    8232              : 
    8233        43969 :   if (exit_bb)
    8234              :     {
    8235        43849 :       free (exit_prob);
    8236        43849 :       free (exit_flag);
    8237        43849 :       free (exit_succ);
    8238              :     }
    8239        43969 :   free (entry_prob);
    8240        43969 :   free (entry_flag);
    8241        43969 :   free (entry_pred);
    8242        43969 :   bbs.release ();
    8243              : 
    8244        43969 :   return bb;
    8245        43969 : }
    8246              : 
    8247              : /* Dump default def DEF to file FILE using FLAGS and indentation
    8248              :    SPC.  */
    8249              : 
    8250              : static void
    8251          551 : dump_default_def (FILE *file, tree def, int spc, dump_flags_t flags)
    8252              : {
    8253         1653 :   for (int i = 0; i < spc; ++i)
    8254         1102 :     fprintf (file, " ");
    8255          551 :   dump_ssaname_info_to_file (file, def, spc);
    8256              : 
    8257          551 :   print_generic_expr (file, TREE_TYPE (def), flags);
    8258          551 :   fprintf (file, " ");
    8259          551 :   print_generic_expr (file, def, flags);
    8260          551 :   fprintf (file, " = ");
    8261          551 :   print_generic_expr (file, SSA_NAME_VAR (def), flags);
    8262          551 :   fprintf (file, ";\n");
    8263          551 : }
    8264              : 
    8265              : /* Print no_sanitize attribute to FILE for a given attribute VALUE.  */
    8266              : 
    8267              : static void
    8268           69 : print_no_sanitize_attr_value (FILE *file, tree value)
    8269              : {
    8270           69 :   sanitize_code_type flags = tree_to_sanitize_code_type (value);
    8271           69 :   bool first = true;
    8272         2415 :   for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
    8273              :     {
    8274         2346 :       if ((sanitizer_opts[i].flag & flags) == sanitizer_opts[i].flag)
    8275              :         {
    8276          289 :           if (!first)
    8277          220 :             fprintf (file, " | ");
    8278          289 :           fprintf (file, "%s", sanitizer_opts[i].name);
    8279          289 :           first = false;
    8280              :         }
    8281              :     }
    8282           69 : }
    8283              : 
    8284              : /* Dump FUNCTION_DECL FN to file FILE using FLAGS (see TDF_* in dumpfile.h)
    8285              :    */
    8286              : 
    8287              : void
    8288        65820 : dump_function_to_file (tree fndecl, FILE *file, dump_flags_t flags)
    8289              : {
    8290        65820 :   tree arg, var, old_current_fndecl = current_function_decl;
    8291        65820 :   struct function *dsf;
    8292        65820 :   bool ignore_topmost_bind = false, any_var = false;
    8293        65820 :   basic_block bb;
    8294        65820 :   tree chain;
    8295        65820 :   bool tmclone = (TREE_CODE (fndecl) == FUNCTION_DECL
    8296       125943 :                   && decl_is_tm_clone (fndecl));
    8297        65820 :   struct function *fun = DECL_STRUCT_FUNCTION (fndecl);
    8298              : 
    8299        65820 :   tree fntype = TREE_TYPE (fndecl);
    8300        65820 :   tree attrs[] = { DECL_ATTRIBUTES (fndecl), TYPE_ATTRIBUTES (fntype) };
    8301              : 
    8302       197460 :   for (int i = 0; i != 2; ++i)
    8303              :     {
    8304       131640 :       if (!attrs[i])
    8305       107336 :         continue;
    8306              : 
    8307        24304 :       fprintf (file, "__attribute__((");
    8308              : 
    8309        24304 :       bool first = true;
    8310        24304 :       tree chain;
    8311        92138 :       for (chain = attrs[i]; chain; first = false, chain = TREE_CHAIN (chain))
    8312              :         {
    8313        43530 :           if (!first)
    8314        19226 :             fprintf (file, ", ");
    8315              : 
    8316        43530 :           tree name = get_attribute_name (chain);
    8317        43530 :           print_generic_expr (file, name, flags);
    8318        43530 :           if (TREE_VALUE (chain) != NULL_TREE)
    8319              :             {
    8320        11219 :               fprintf (file, " (");
    8321              : 
    8322        11219 :               if (strstr (IDENTIFIER_POINTER (name), "no_sanitize"))
    8323           69 :                 print_no_sanitize_attr_value (file, TREE_VALUE (chain));
    8324        11150 :               else if (!strcmp (IDENTIFIER_POINTER (name),
    8325              :                                 "omp declare variant base"))
    8326              :                 {
    8327          230 :                   tree a = TREE_VALUE (chain);
    8328          230 :                   print_generic_expr (file, TREE_PURPOSE (a), flags);
    8329          230 :                   fprintf (file, " match ");
    8330          230 :                   print_omp_context_selector (file, TREE_VALUE (a),
    8331              :                                               flags);
    8332              :                 }
    8333              :               else
    8334        10920 :                 print_generic_expr (file, TREE_VALUE (chain), flags);
    8335        11219 :               fprintf (file, ")");
    8336              :             }
    8337              :         }
    8338              : 
    8339        24304 :       fprintf (file, "))\n");
    8340              :     }
    8341              : 
    8342        65820 :   current_function_decl = fndecl;
    8343        65820 :   if (flags & TDF_GIMPLE)
    8344              :     {
    8345           44 :       static bool hotness_bb_param_printed = false;
    8346           44 :       if (profile_info != NULL
    8347            0 :           && !hotness_bb_param_printed)
    8348              :         {
    8349            0 :           hotness_bb_param_printed = true;
    8350            0 :           fprintf (file,
    8351              :                    "/* --param=gimple-fe-computed-hot-bb-threshold=%" PRId64
    8352              :                    " */\n", get_hot_bb_threshold ());
    8353              :         }
    8354              : 
    8355           44 :       print_generic_expr (file, TREE_TYPE (TREE_TYPE (fndecl)),
    8356              :                           flags | TDF_SLIM);
    8357           44 :       fprintf (file, " __GIMPLE (%s",
    8358           44 :                (fun->curr_properties & PROP_ssa) ? "ssa"
    8359            9 :                : (fun->curr_properties & PROP_cfg) ? "cfg"
    8360              :                : "");
    8361              : 
    8362           44 :       if (fun && fun->cfg)
    8363              :         {
    8364           40 :           basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (fun);
    8365           40 :           if (bb->count.initialized_p ())
    8366            0 :             fprintf (file, ",%s(%" PRIu64 ")",
    8367              :                      profile_quality_as_string (bb->count.quality ()),
    8368              :                      bb->count.value ());
    8369           40 :           if (flags & TDF_UID)
    8370            0 :             fprintf (file, ")\n%sD_%u (", function_name (fun),
    8371            0 :                      DECL_UID (fndecl));
    8372              :           else
    8373           40 :             fprintf (file, ")\n%s (", function_name (fun));
    8374              :         }
    8375              :     }
    8376              :   else
    8377              :     {
    8378        65776 :       print_generic_expr (file, TREE_TYPE (fntype), flags);
    8379        65776 :       if (flags & TDF_UID)
    8380         1298 :         fprintf (file, " %sD.%u %s(", function_name (fun), DECL_UID (fndecl),
    8381              :                  tmclone ? "[tm-clone] " : "");
    8382              :       else
    8383       130217 :         fprintf (file, " %s %s(", function_name (fun),
    8384              :                  tmclone ? "[tm-clone] " : "");
    8385              :     }
    8386              : 
    8387        65820 :   arg = DECL_ARGUMENTS (fndecl);
    8388       155583 :   while (arg)
    8389              :     {
    8390        89763 :       print_generic_expr (file, TREE_TYPE (arg), flags);
    8391        89763 :       fprintf (file, " ");
    8392        89763 :       print_generic_expr (file, arg, flags);
    8393        89763 :       if (DECL_CHAIN (arg))
    8394        45829 :         fprintf (file, ", ");
    8395        89763 :       arg = DECL_CHAIN (arg);
    8396              :     }
    8397        65820 :   fprintf (file, ")\n");
    8398              : 
    8399        65820 :   dsf = DECL_STRUCT_FUNCTION (fndecl);
    8400        65820 :   if (dsf && (flags & TDF_EH))
    8401          658 :     dump_eh_tree (file, dsf);
    8402              : 
    8403        65820 :   if (flags & TDF_RAW && !gimple_has_body_p (fndecl))
    8404              :     {
    8405            2 :       dump_node (fndecl, TDF_SLIM | flags, file);
    8406            2 :       current_function_decl = old_current_fndecl;
    8407            2 :       return;
    8408              :     }
    8409              : 
    8410              :   /* When GIMPLE is lowered, the variables are no longer available in
    8411              :      BIND_EXPRs, so display them separately.  */
    8412        65818 :   if (fun && fun->decl == fndecl && (fun->curr_properties & PROP_gimple_lcf))
    8413              :     {
    8414        54534 :       unsigned ix;
    8415        54534 :       ignore_topmost_bind = true;
    8416              : 
    8417        54534 :       fprintf (file, "{\n");
    8418       107855 :       if (gimple_in_ssa_p (fun)
    8419        53321 :           && (flags & TDF_ALIAS))
    8420              :         {
    8421         1230 :           for (arg = DECL_ARGUMENTS (fndecl); arg != NULL;
    8422          577 :                arg = DECL_CHAIN (arg))
    8423              :             {
    8424          577 :               tree def = ssa_default_def (fun, arg);
    8425          577 :               if (def)
    8426          551 :                 dump_default_def (file, def, 2, flags);
    8427              :             }
    8428              : 
    8429          653 :           tree res = DECL_RESULT (fun->decl);
    8430          653 :           if (res != NULL_TREE
    8431          653 :               && DECL_BY_REFERENCE (res))
    8432              :             {
    8433            0 :               tree def = ssa_default_def (fun, res);
    8434            0 :               if (def)
    8435            0 :                 dump_default_def (file, def, 2, flags);
    8436              :             }
    8437              : 
    8438          653 :           tree static_chain = fun->static_chain_decl;
    8439          653 :           if (static_chain != NULL_TREE)
    8440              :             {
    8441            0 :               tree def = ssa_default_def (fun, static_chain);
    8442            0 :               if (def)
    8443            0 :                 dump_default_def (file, def, 2, flags);
    8444              :             }
    8445              :         }
    8446              : 
    8447       104244 :       if (!vec_safe_is_empty (fun->local_decls))
    8448       303011 :         FOR_EACH_LOCAL_DECL (fun, ix, var)
    8449              :           {
    8450       271456 :             print_generic_decl (file, var, flags);
    8451       271456 :             fprintf (file, "\n");
    8452              : 
    8453       271456 :             any_var = true;
    8454              :           }
    8455              : 
    8456        54534 :       tree name;
    8457              : 
    8458        54534 :       if (gimple_in_ssa_p (fun))
    8459      1786386 :         FOR_EACH_SSA_NAME (ix, name, fun)
    8460              :           {
    8461      1296771 :             if (!SSA_NAME_VAR (name)
    8462              :                 /* SSA name with decls without a name still get
    8463              :                    dumped as _N, list those explicitly as well even
    8464              :                    though we've dumped the decl declaration as D.xxx
    8465              :                    above.  */
    8466       752035 :                 || !SSA_NAME_IDENTIFIER (name))
    8467              :               {
    8468       547458 :                 fprintf (file, "  ");
    8469       547458 :                 print_generic_expr (file, TREE_TYPE (name), flags);
    8470       547458 :                 fprintf (file, " ");
    8471       547458 :                 print_generic_expr (file, name, flags);
    8472       547458 :                 fprintf (file, ";\n");
    8473              : 
    8474       547458 :                 any_var = true;
    8475              :               }
    8476              :           }
    8477              :     }
    8478              : 
    8479        65818 :   if (fun && fun->decl == fndecl
    8480        65818 :       && fun->cfg
    8481        54256 :       && basic_block_info_for_fn (fun))
    8482              :     {
    8483              :       /* If the CFG has been built, emit a CFG-based dump.  */
    8484        54256 :       if (!ignore_topmost_bind)
    8485            0 :         fprintf (file, "{\n");
    8486              : 
    8487        54256 :       if (any_var && n_basic_blocks_for_fn (fun))
    8488        47151 :         fprintf (file, "\n");
    8489              : 
    8490       321854 :       FOR_EACH_BB_FN (bb, fun)
    8491       267598 :         dump_bb (file, bb, 2, flags);
    8492              : 
    8493        54256 :       fprintf (file, "}\n");
    8494              :     }
    8495        11562 :   else if (fun && (fun->curr_properties & PROP_gimple_any))
    8496              :     {
    8497              :       /* The function is now in GIMPLE form but the CFG has not been
    8498              :          built yet.  Emit the single sequence of GIMPLE statements
    8499              :          that make up its body.  */
    8500         5321 :       gimple_seq body = gimple_body (fndecl);
    8501              : 
    8502         5321 :       if (gimple_seq_first_stmt (body)
    8503         5321 :           && gimple_seq_first_stmt (body) == gimple_seq_last_stmt (body)
    8504        10376 :           && gimple_code (gimple_seq_first_stmt (body)) == GIMPLE_BIND)
    8505         5043 :         print_gimple_seq (file, body, 0, flags);
    8506              :       else
    8507              :         {
    8508          278 :           if (!ignore_topmost_bind)
    8509            0 :             fprintf (file, "{\n");
    8510              : 
    8511          278 :           if (any_var)
    8512          186 :             fprintf (file, "\n");
    8513              : 
    8514          278 :           print_gimple_seq (file, body, 2, flags);
    8515          278 :           fprintf (file, "}\n");
    8516              :         }
    8517              :     }
    8518              :   else
    8519              :     {
    8520         6241 :       int indent;
    8521              : 
    8522              :       /* Make a tree based dump.  */
    8523         6241 :       chain = DECL_SAVED_TREE (fndecl);
    8524         6241 :       if (chain && TREE_CODE (chain) == BIND_EXPR)
    8525              :         {
    8526         6241 :           if (ignore_topmost_bind)
    8527              :             {
    8528            0 :               chain = BIND_EXPR_BODY (chain);
    8529            0 :               indent = 2;
    8530              :             }
    8531              :           else
    8532              :             indent = 0;
    8533              :         }
    8534              :       else
    8535              :         {
    8536            0 :           if (!ignore_topmost_bind)
    8537              :             {
    8538            0 :               fprintf (file, "{\n");
    8539              :               /* No topmost bind, pretend it's ignored for later.  */
    8540            0 :               ignore_topmost_bind = true;
    8541              :             }
    8542              :           indent = 2;
    8543              :         }
    8544              : 
    8545         6241 :       if (any_var)
    8546            0 :         fprintf (file, "\n");
    8547              : 
    8548         6241 :       print_generic_stmt_indented (file, chain, flags, indent);
    8549         6241 :       if (ignore_topmost_bind)
    8550            0 :         fprintf (file, "}\n");
    8551              :     }
    8552              : 
    8553        65818 :   if (flags & TDF_ENUMERATE_LOCALS)
    8554           39 :     dump_enumerated_decls (file, flags);
    8555        65818 :   fprintf (file, "\n\n");
    8556              : 
    8557        65818 :   current_function_decl = old_current_fndecl;
    8558              : }
    8559              : 
    8560              : /* Dump FUNCTION_DECL FN to stderr using FLAGS (see TDF_* in tree.h)  */
    8561              : 
    8562              : DEBUG_FUNCTION void
    8563            0 : debug_function (tree fn, dump_flags_t flags)
    8564              : {
    8565            0 :   dump_function_to_file (fn, stderr, flags);
    8566            0 : }
    8567              : 
    8568              : 
    8569              : /* Print on FILE the indexes for the predecessors of basic_block BB.  */
    8570              : 
    8571              : static void
    8572         5344 : print_pred_bbs (FILE *file, basic_block bb)
    8573              : {
    8574         5344 :   edge e;
    8575         5344 :   edge_iterator ei;
    8576              : 
    8577        12101 :   FOR_EACH_EDGE (e, ei, bb->preds)
    8578         6757 :     fprintf (file, "bb_%d ", e->src->index);
    8579         5344 : }
    8580              : 
    8581              : 
    8582              : /* Print on FILE the indexes for the successors of basic_block BB.  */
    8583              : 
    8584              : static void
    8585         5344 : print_succ_bbs (FILE *file, basic_block bb)
    8586              : {
    8587         5344 :   edge e;
    8588         5344 :   edge_iterator ei;
    8589              : 
    8590        12196 :   FOR_EACH_EDGE (e, ei, bb->succs)
    8591         6852 :     fprintf (file, "bb_%d ", e->dest->index);
    8592         5344 : }
    8593              : 
    8594              : /* Print to FILE the basic block BB following the VERBOSITY level.  */
    8595              : 
    8596              : void
    8597         5344 : print_loops_bb (FILE *file, basic_block bb, int indent, int verbosity)
    8598              : {
    8599         5344 :   char *s_indent = (char *) alloca ((size_t) indent + 1);
    8600         5344 :   memset ((void *) s_indent, ' ', (size_t) indent);
    8601         5344 :   s_indent[indent] = '\0';
    8602              : 
    8603              :   /* Print basic_block's header.  */
    8604         5344 :   if (verbosity >= 2)
    8605              :     {
    8606         5344 :       fprintf (file, "%s  bb_%d (preds = {", s_indent, bb->index);
    8607         5344 :       print_pred_bbs (file, bb);
    8608         5344 :       fprintf (file, "}, succs = {");
    8609         5344 :       print_succ_bbs (file, bb);
    8610         5344 :       fprintf (file, "})\n");
    8611              :     }
    8612              : 
    8613              :   /* Print basic_block's body.  */
    8614         5344 :   if (verbosity >= 3)
    8615              :     {
    8616         2928 :       fprintf (file, "%s  {\n", s_indent);
    8617         2928 :       dump_bb (file, bb, indent + 4, TDF_VOPS|TDF_MEMSYMS);
    8618         2928 :       fprintf (file, "%s  }\n", s_indent);
    8619              :     }
    8620         5344 : }
    8621              : 
    8622              : /* Print loop information.  */
    8623              : 
    8624              : void
    8625         9782 : print_loop_info (FILE *file, const class loop *loop, const char *prefix)
    8626              : {
    8627         9782 :   if (loop->can_be_parallel)
    8628            0 :     fprintf (file, ", can_be_parallel");
    8629         9782 :   if (loop->warned_aggressive_loop_optimizations)
    8630            0 :     fprintf (file, ", warned_aggressive_loop_optimizations");
    8631         9782 :   if (loop->dont_vectorize)
    8632            5 :     fprintf (file, ", dont_vectorize");
    8633         9782 :   if (loop->force_vectorize)
    8634            0 :     fprintf (file, ", force_vectorize");
    8635         9782 :   if (loop->in_oacc_kernels_region)
    8636          181 :     fprintf (file, ", in_oacc_kernels_region");
    8637         9782 :   if (loop->finite_p)
    8638         2009 :     fprintf (file, ", finite_p");
    8639         9782 :   if (loop->unroll)
    8640           68 :     fprintf (file, "\n%sunroll %d", prefix, loop->unroll);
    8641         9782 :   if (loop->nb_iterations)
    8642              :     {
    8643           35 :       fprintf (file, "\n%sniter ", prefix);
    8644           35 :       print_generic_expr (file, loop->nb_iterations);
    8645              :     }
    8646              : 
    8647         9782 :   if (loop->any_upper_bound)
    8648              :     {
    8649         1960 :       fprintf (file, "\n%supper_bound ", prefix);
    8650         1960 :       print_decu (loop->nb_iterations_upper_bound, file);
    8651              :     }
    8652         9782 :   if (loop->any_likely_upper_bound)
    8653              :     {
    8654         1960 :       fprintf (file, "\n%slikely_upper_bound ", prefix);
    8655         1960 :       print_decu (loop->nb_iterations_likely_upper_bound, file);
    8656              :     }
    8657              : 
    8658         9782 :   if (loop->any_estimate)
    8659              :     {
    8660          934 :       fprintf (file, "\n%sestimate ", prefix);
    8661          934 :       print_decu (loop->nb_iterations_estimate, file);
    8662              :     }
    8663         9782 :   bool reliable;
    8664         9782 :   sreal iterations;
    8665         9782 :   if (loop->num && expected_loop_iterations_by_profile (loop, &iterations, &reliable))
    8666              :     {
    8667         5055 :       fprintf (file, "\n%siterations by profile: %f (%s%s) entry count:", prefix,
    8668              :                iterations.to_double (), reliable ? "reliable" : "unreliable",
    8669         2306 :                maybe_flat_loop_profile (loop) ? ", maybe flat" : "");
    8670         2306 :       loop_count_in (loop).dump (file, cfun);
    8671              :     }
    8672              : 
    8673         9782 : }
    8674              : 
    8675              : static void print_loop_and_siblings (FILE *, class loop *, int, int);
    8676              : 
    8677              : /* Pretty print LOOP on FILE, indented INDENT spaces.  Following
    8678              :    VERBOSITY level this outputs the contents of the loop, or just its
    8679              :    structure.  */
    8680              : 
    8681              : static void
    8682         1266 : print_loop (FILE *file, class loop *loop, int indent, int verbosity)
    8683              : {
    8684         1266 :   char *s_indent;
    8685         1266 :   basic_block bb;
    8686              : 
    8687         1266 :   if (loop == NULL)
    8688              :     return;
    8689              : 
    8690         1266 :   s_indent = (char *) alloca ((size_t) indent + 1);
    8691         1266 :   memset ((void *) s_indent, ' ', (size_t) indent);
    8692         1266 :   s_indent[indent] = '\0';
    8693              : 
    8694              :   /* Print loop's header.  */
    8695         1266 :   fprintf (file, "%sloop_%d (", s_indent, loop->num);
    8696         1266 :   if (loop->header)
    8697         1266 :     fprintf (file, "header = %d", loop->header->index);
    8698              :   else
    8699              :     {
    8700            0 :       fprintf (file, "deleted)\n");
    8701            0 :       return;
    8702              :     }
    8703         1266 :   if (loop->latch)
    8704         1266 :     fprintf (file, ", latch = %d", loop->latch->index);
    8705              :   else
    8706            0 :     fprintf (file, ", multiple latches");
    8707         1266 :   print_loop_info (file, loop, s_indent);
    8708         1266 :   fprintf (file, ")\n");
    8709              : 
    8710              :   /* Print loop's body.  */
    8711         1266 :   if (verbosity >= 1)
    8712              :     {
    8713         1266 :       fprintf (file, "%s{\n", s_indent);
    8714        21548 :       FOR_EACH_BB_FN (bb, cfun)
    8715        20282 :         if (bb->loop_father == loop)
    8716         4832 :           print_loops_bb (file, bb, indent, verbosity);
    8717              : 
    8718         1266 :       print_loop_and_siblings (file, loop->inner, indent + 2, verbosity);
    8719         1266 :       fprintf (file, "%s}\n", s_indent);
    8720              :     }
    8721              : }
    8722              : 
    8723              : /* Print the LOOP and its sibling loops on FILE, indented INDENT
    8724              :    spaces.  Following VERBOSITY level this outputs the contents of the
    8725              :    loop, or just its structure.  */
    8726              : 
    8727              : static void
    8728         1266 : print_loop_and_siblings (FILE *file, class loop *loop, int indent,
    8729              :                          int verbosity)
    8730              : {
    8731         2154 :   if (loop == NULL)
    8732         1266 :     return;
    8733              : 
    8734         1266 :   print_loop (file, loop, indent, verbosity);
    8735          378 :   print_loop_and_siblings (file, loop->next, indent, verbosity);
    8736              : }
    8737              : 
    8738              : /* Follow a CFG edge from the entry point of the program, and on entry
    8739              :    of a loop, pretty print the loop structure on FILE.  */
    8740              : 
    8741              : void
    8742          378 : print_loops (FILE *file, int verbosity)
    8743              : {
    8744          378 :   basic_block bb;
    8745              : 
    8746          378 :   bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
    8747          378 :   fprintf (file, "\nLoops in function: %s\n", current_function_name ());
    8748          378 :   if (bb && bb->loop_father)
    8749          756 :     print_loop_and_siblings (file, bb->loop_father, 0, verbosity);
    8750          378 : }
    8751              : 
    8752              : /* Dump a loop.  */
    8753              : 
    8754              : DEBUG_FUNCTION void
    8755            0 : debug (class loop &ref)
    8756              : {
    8757            0 :   print_loop (stderr, &ref, 0, /*verbosity*/0);
    8758            0 : }
    8759              : 
    8760              : DEBUG_FUNCTION void
    8761            0 : debug (class loop *ptr)
    8762              : {
    8763            0 :   if (ptr)
    8764            0 :     debug (*ptr);
    8765              :   else
    8766            0 :     fprintf (stderr, "<nil>\n");
    8767            0 : }
    8768              : 
    8769              : /* Dump a loop verbosely.  */
    8770              : 
    8771              : DEBUG_FUNCTION void
    8772            0 : debug_verbose (class loop &ref)
    8773              : {
    8774            0 :   print_loop (stderr, &ref, 0, /*verbosity*/3);
    8775            0 : }
    8776              : 
    8777              : DEBUG_FUNCTION void
    8778            0 : debug_verbose (class loop *ptr)
    8779              : {
    8780            0 :   if (ptr)
    8781            0 :     debug (*ptr);
    8782              :   else
    8783            0 :     fprintf (stderr, "<nil>\n");
    8784            0 : }
    8785              : 
    8786              : 
    8787              : /* Debugging loops structure at tree level, at some VERBOSITY level.  */
    8788              : 
    8789              : DEBUG_FUNCTION void
    8790            0 : debug_loops (int verbosity)
    8791              : {
    8792            0 :   print_loops (stderr, verbosity);
    8793            0 : }
    8794              : 
    8795              : /* Print on stderr the code of LOOP, at some VERBOSITY level.  */
    8796              : 
    8797              : DEBUG_FUNCTION void
    8798            0 : debug_loop (class loop *loop, int verbosity)
    8799              : {
    8800            0 :   print_loop (stderr, loop, 0, verbosity);
    8801            0 : }
    8802              : 
    8803              : /* Print on stderr the code of loop number NUM, at some VERBOSITY
    8804              :    level.  */
    8805              : 
    8806              : DEBUG_FUNCTION void
    8807            0 : debug_loop_num (unsigned num, int verbosity)
    8808              : {
    8809            0 :   debug_loop (get_loop (cfun, num), verbosity);
    8810            0 : }
    8811              : 
    8812              : /* Return true if BB ends with a call, possibly followed by some
    8813              :    instructions that must stay with the call.  Return false,
    8814              :    otherwise.  */
    8815              : 
    8816              : static bool
    8817            3 : gimple_block_ends_with_call_p (basic_block bb)
    8818              : {
    8819            3 :   gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);
    8820            3 :   return !gsi_end_p (gsi) && is_gimple_call (gsi_stmt (gsi));
    8821              : }
    8822              : 
    8823              : 
    8824              : /* Return true if BB ends with a conditional branch.  Return false,
    8825              :    otherwise.  */
    8826              : 
    8827              : static bool
    8828         1796 : gimple_block_ends_with_condjump_p (const_basic_block bb)
    8829              : {
    8830         3592 :   return safe_is_a <gcond *> (*gsi_last_bb (const_cast <basic_block> (bb)));
    8831              : }
    8832              : 
    8833              : 
    8834              : /* Return true if statement T may terminate execution of BB in ways not
    8835              :    explicitly represtented in the CFG.  */
    8836              : 
    8837              : bool
    8838    455238303 : stmt_can_terminate_bb_p (gimple *t)
    8839              : {
    8840    455238303 :   tree fndecl = NULL_TREE;
    8841    455238303 :   int call_flags = 0;
    8842              : 
    8843              :   /* Eh exception not handled internally terminates execution of the whole
    8844              :      function.  */
    8845    455238303 :   if (stmt_can_throw_external (cfun, t))
    8846              :     return true;
    8847              : 
    8848              :   /* NORETURN and LONGJMP calls already have an edge to exit.
    8849              :      CONST and PURE calls do not need one.
    8850              :      We don't currently check for CONST and PURE here, although
    8851              :      it would be a good idea, because those attributes are
    8852              :      figured out from the RTL in mark_constant_function, and
    8853              :      the counter incrementation code from -fprofile-arcs
    8854              :      leads to different results from -fbranch-probabilities.  */
    8855    447121936 :   if (is_gimple_call (t))
    8856              :     {
    8857     14779270 :       fndecl = gimple_call_fndecl (t);
    8858     14779270 :       call_flags = gimple_call_flags (t);
    8859              :     }
    8860              : 
    8861    447121936 :   if (is_gimple_call (t)
    8862     14779270 :       && fndecl
    8863     12852834 :       && fndecl_built_in_p (fndecl)
    8864      5227163 :       && (call_flags & ECF_NOTHROW)
    8865      4539830 :       && !(call_flags & ECF_RETURNS_TWICE)
    8866              :       /* fork() doesn't really return twice, but the effect of
    8867              :          wrapping it in __gcov_fork() which calls __gcov_dump() and
    8868              :          __gcov_reset() and clears the counters before forking has the same
    8869              :          effect as returning twice.  Force a fake edge.  */
    8870    451661399 :       && !fndecl_built_in_p (fndecl, BUILT_IN_FORK))
    8871              :     return false;
    8872              : 
    8873    442582688 :   if (is_gimple_call (t))
    8874              :     {
    8875     10240022 :       edge_iterator ei;
    8876     10240022 :       edge e;
    8877     10240022 :       basic_block bb;
    8878              : 
    8879     10240022 :       if (call_flags & (ECF_PURE | ECF_CONST)
    8880      2111130 :           && !(call_flags & ECF_LOOPING_CONST_OR_PURE))
    8881      9062575 :         return false;
    8882              : 
    8883              :       /* Function call may do longjmp, terminate program or do other things.
    8884              :          Special case noreturn that have non-abnormal edges out as in this case
    8885              :          the fact is sufficiently represented by lack of edges out of T.  */
    8886      8257684 :       if (!(call_flags & ECF_NORETURN))
    8887              :         return true;
    8888              : 
    8889      1277502 :       bb = gimple_bb (t);
    8890      2110406 :       FOR_EACH_EDGE (e, ei, bb->succs)
    8891       932959 :         if ((e->flags & EDGE_FAKE) == 0)
    8892              :           return true;
    8893              :     }
    8894              : 
    8895    433520113 :   if (gasm *asm_stmt = dyn_cast <gasm *> (t))
    8896       317025 :     if (gimple_asm_volatile_p (asm_stmt) || gimple_asm_basic_p (asm_stmt))
    8897              :       return true;
    8898              : 
    8899              :   return false;
    8900              : }
    8901              : 
    8902              : 
    8903              : /* Add fake edges to the function exit for any non constant and non
    8904              :    noreturn calls (or noreturn calls with EH/abnormal edges),
    8905              :    volatile inline assembly in the bitmap of blocks specified by BLOCKS
    8906              :    or to the whole CFG if BLOCKS is zero.  Return the number of blocks
    8907              :    that were split.
    8908              : 
    8909              :    The goal is to expose cases in which entering a basic block does
    8910              :    not imply that all subsequent instructions must be executed.  */
    8911              : 
    8912              : static int
    8913         3012 : gimple_flow_call_edges_add (sbitmap blocks)
    8914              : {
    8915         3012 :   int i;
    8916         3012 :   int blocks_split = 0;
    8917         3012 :   int last_bb = last_basic_block_for_fn (cfun);
    8918         3012 :   bool check_last_block = false;
    8919              : 
    8920         3012 :   if (n_basic_blocks_for_fn (cfun) == NUM_FIXED_BLOCKS)
    8921              :     return 0;
    8922              : 
    8923         3012 :   if (! blocks)
    8924              :     check_last_block = true;
    8925              :   else
    8926            0 :     check_last_block = bitmap_bit_p (blocks,
    8927            0 :                                      EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb->index);
    8928              : 
    8929              :   /* In the last basic block, before epilogue generation, there will be
    8930              :      a fallthru edge to EXIT.  Special care is required if the last insn
    8931              :      of the last basic block is a call because make_edge folds duplicate
    8932              :      edges, which would result in the fallthru edge also being marked
    8933              :      fake, which would result in the fallthru edge being removed by
    8934              :      remove_fake_edges, which would result in an invalid CFG.
    8935              : 
    8936              :      Moreover, we can't elide the outgoing fake edge, since the block
    8937              :      profiler needs to take this into account in order to solve the minimal
    8938              :      spanning tree in the case that the call doesn't return.
    8939              : 
    8940              :      Handle this by adding a dummy instruction in a new last basic block.  */
    8941            0 :   if (check_last_block)
    8942              :     {
    8943         3012 :       basic_block bb = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
    8944         3012 :       gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);
    8945         3012 :       gimple *t = NULL;
    8946              : 
    8947         3012 :       if (!gsi_end_p (gsi))
    8948         3000 :         t = gsi_stmt (gsi);
    8949              : 
    8950         3000 :       if (t && stmt_can_terminate_bb_p (t))
    8951              :         {
    8952          197 :           edge e;
    8953              : 
    8954          197 :           e = find_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun));
    8955          197 :           if (e)
    8956              :             {
    8957            0 :               gsi_insert_on_edge (e, gimple_build_nop ());
    8958            0 :               gsi_commit_edge_inserts ();
    8959              :             }
    8960              :         }
    8961              :     }
    8962              : 
    8963              :   /* Now add fake edges to the function exit for any non constant
    8964              :      calls since there is no way that we can determine if they will
    8965              :      return or not...  */
    8966        23049 :   for (i = 0; i < last_bb; i++)
    8967              :     {
    8968        20037 :       basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
    8969        20037 :       gimple_stmt_iterator gsi;
    8970        20037 :       gimple *stmt, *last_stmt;
    8971              : 
    8972        20037 :       if (!bb)
    8973            6 :         continue;
    8974              : 
    8975        20031 :       if (blocks && !bitmap_bit_p (blocks, i))
    8976            0 :         continue;
    8977              : 
    8978        20031 :       gsi = gsi_last_nondebug_bb (bb);
    8979        20031 :       if (!gsi_end_p (gsi))
    8980              :         {
    8981              :           last_stmt = gsi_stmt (gsi);
    8982        30943 :           do
    8983              :             {
    8984        30943 :               stmt = gsi_stmt (gsi);
    8985        30943 :               if (stmt_can_terminate_bb_p (stmt))
    8986              :                 {
    8987         4933 :                   edge e;
    8988              : 
    8989              :                   /* The handling above of the final block before the
    8990              :                      epilogue should be enough to verify that there is
    8991              :                      no edge to the exit block in CFG already.
    8992              :                      Calling make_edge in such case would cause us to
    8993              :                      mark that edge as fake and remove it later.  */
    8994         4933 :                   if (flag_checking && stmt == last_stmt)
    8995              :                     {
    8996         1632 :                       e = find_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun));
    8997         1632 :                       gcc_assert (e == NULL);
    8998              :                     }
    8999              : 
    9000              :                   /* Note that the following may create a new basic block
    9001              :                      and renumber the existing basic blocks.  */
    9002         4933 :                   if (stmt != last_stmt)
    9003              :                     {
    9004         3301 :                       e = split_block (bb, stmt);
    9005         3301 :                       if (e)
    9006         3301 :                         blocks_split++;
    9007              :                     }
    9008         4933 :                   e = make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_FAKE);
    9009         4933 :                   e->probability = profile_probability::guessed_never ();
    9010              :                 }
    9011        30943 :               gsi_prev (&gsi);
    9012              :             }
    9013        30943 :           while (!gsi_end_p (gsi));
    9014              :         }
    9015              :     }
    9016              : 
    9017         3012 :   if (blocks_split)
    9018         1237 :     checking_verify_flow_info ();
    9019              : 
    9020              :   return blocks_split;
    9021              : }
    9022              : 
    9023              : /* Removes edge E and all the blocks dominated by it, and updates dominance
    9024              :    information.  The IL in E->src needs to be updated separately.
    9025              :    If dominance info is not available, only the edge E is removed.*/
    9026              : 
    9027              : void
    9028      3820351 : remove_edge_and_dominated_blocks (edge e)
    9029              : {
    9030      3820351 :   vec<basic_block> bbs_to_fix_dom = vNULL;
    9031      3820351 :   edge f;
    9032      3820351 :   edge_iterator ei;
    9033      3820351 :   bool none_removed = false;
    9034      3820351 :   unsigned i;
    9035      3820351 :   basic_block bb, dbb;
    9036      3820351 :   bitmap_iterator bi;
    9037              : 
    9038              :   /* If we are removing a path inside a non-root loop that may change
    9039              :      loop ownership of blocks or remove loops.  Mark loops for fixup.  */
    9040      3820351 :   class loop *src_loop = e->src->loop_father;
    9041      3820351 :   if (current_loops
    9042      3554620 :       && loop_outer (src_loop) != NULL
    9043      4510385 :       && src_loop == e->dest->loop_father)
    9044              :     {
    9045       279789 :       loops_state_set (LOOPS_NEED_FIXUP);
    9046              :       /* If we are removing a backedge clear the number of iterations
    9047              :          and estimates.  */
    9048       279789 :       class loop *dest_loop = e->dest->loop_father;
    9049       279789 :       if (e->dest == src_loop->header
    9050       279789 :           || (e->dest == dest_loop->header
    9051            0 :               && flow_loop_nested_p (dest_loop, src_loop)))
    9052              :         {
    9053         9301 :           free_numbers_of_iterations_estimates (dest_loop);
    9054              :           /* If we removed the last backedge mark the loop for removal.  */
    9055        27823 :           FOR_EACH_EDGE (f, ei, dest_loop->header->preds)
    9056        18733 :             if (f != e
    9057        18733 :                 && (f->src->loop_father == dest_loop
    9058         9303 :                     || flow_loop_nested_p (dest_loop, f->src->loop_father)))
    9059              :               break;
    9060         9301 :           if (!f)
    9061         9090 :             mark_loop_for_removal (dest_loop);
    9062              :         }
    9063              :     }
    9064              : 
    9065      3820351 :   if (!dom_info_available_p (CDI_DOMINATORS))
    9066              :     {
    9067      3624900 :       remove_edge (e);
    9068      7249800 :       return;
    9069              :     }
    9070              : 
    9071              :   /* No updating is needed for edges to exit.  */
    9072       195451 :   if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
    9073              :     {
    9074            0 :       if (cfgcleanup_altered_bbs)
    9075            0 :         bitmap_set_bit (cfgcleanup_altered_bbs, e->src->index);
    9076            0 :       remove_edge (e);
    9077            0 :       return;
    9078              :     }
    9079              : 
    9080              :   /* First, we find the basic blocks to remove.  If E->dest has a predecessor
    9081              :      that is not dominated by E->dest, then this set is empty.  Otherwise,
    9082              :      all the basic blocks dominated by E->dest are removed.
    9083              : 
    9084              :      Also, to DF_IDOM we store the immediate dominators of the blocks in
    9085              :      the dominance frontier of E (i.e., of the successors of the
    9086              :      removed blocks, if there are any, and of E->dest otherwise).  */
    9087       208622 :   FOR_EACH_EDGE (f, ei, e->dest->preds)
    9088              :     {
    9089       203525 :       if (f == e)
    9090        13130 :         continue;
    9091              : 
    9092       190395 :       if (!dominated_by_p (CDI_DOMINATORS, f->src, e->dest))
    9093              :         {
    9094              :           none_removed = true;
    9095              :           break;
    9096              :         }
    9097              :     }
    9098              : 
    9099       195451 :   auto_bitmap df, df_idom;
    9100       195451 :   auto_vec<basic_block> bbs_to_remove;
    9101       195451 :   if (none_removed)
    9102       190354 :     bitmap_set_bit (df_idom,
    9103       190354 :                     get_immediate_dominator (CDI_DOMINATORS, e->dest)->index);
    9104              :   else
    9105              :     {
    9106         5097 :       bbs_to_remove = get_all_dominated_blocks (CDI_DOMINATORS, e->dest);
    9107        11580 :       FOR_EACH_VEC_ELT (bbs_to_remove, i, bb)
    9108              :         {
    9109        13096 :           FOR_EACH_EDGE (f, ei, bb->succs)
    9110              :             {
    9111         6613 :               if (f->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
    9112         6611 :                 bitmap_set_bit (df, f->dest->index);
    9113              :             }
    9114              :         }
    9115        11580 :       FOR_EACH_VEC_ELT (bbs_to_remove, i, bb)
    9116         6483 :         bitmap_clear_bit (df, bb->index);
    9117              : 
    9118         9908 :       EXECUTE_IF_SET_IN_BITMAP (df, 0, i, bi)
    9119              :         {
    9120         4811 :           bb = BASIC_BLOCK_FOR_FN (cfun, i);
    9121         4811 :           bitmap_set_bit (df_idom,
    9122         4811 :                           get_immediate_dominator (CDI_DOMINATORS, bb)->index);
    9123              :         }
    9124              :     }
    9125              : 
    9126       195451 :   if (cfgcleanup_altered_bbs)
    9127              :     {
    9128              :       /* Record the set of the altered basic blocks.  */
    9129        12602 :       bitmap_set_bit (cfgcleanup_altered_bbs, e->src->index);
    9130        12602 :       bitmap_ior_into (cfgcleanup_altered_bbs, df);
    9131              :     }
    9132              : 
    9133              :   /* Remove E and the cancelled blocks.  */
    9134       195451 :   if (none_removed)
    9135       190354 :     remove_edge (e);
    9136              :   else
    9137              :     {
    9138              :       /* Walk backwards so as to get a chance to substitute all
    9139              :          released DEFs into debug stmts.  See
    9140              :          eliminate_unnecessary_stmts() in tree-ssa-dce.cc for more
    9141              :          details.  */
    9142        16677 :       for (i = bbs_to_remove.length (); i-- > 0; )
    9143         6483 :         delete_basic_block (bbs_to_remove[i]);
    9144              :     }
    9145              : 
    9146              :   /* Update the dominance information.  The immediate dominator may change only
    9147              :      for blocks whose immediate dominator belongs to DF_IDOM:
    9148              : 
    9149              :      Suppose that idom(X) = Y before removal of E and idom(X) != Y after the
    9150              :      removal.  Let Z the arbitrary block such that idom(Z) = Y and
    9151              :      Z dominates X after the removal.  Before removal, there exists a path P
    9152              :      from Y to X that avoids Z.  Let F be the last edge on P that is
    9153              :      removed, and let W = F->dest.  Before removal, idom(W) = Y (since Y
    9154              :      dominates W, and because of P, Z does not dominate W), and W belongs to
    9155              :      the dominance frontier of E.  Therefore, Y belongs to DF_IDOM.  */
    9156       389956 :   EXECUTE_IF_SET_IN_BITMAP (df_idom, 0, i, bi)
    9157              :     {
    9158       194505 :       bb = BASIC_BLOCK_FOR_FN (cfun, i);
    9159       194505 :       for (dbb = first_dom_son (CDI_DOMINATORS, bb);
    9160       688017 :            dbb;
    9161       493512 :            dbb = next_dom_son (CDI_DOMINATORS, dbb))
    9162       493512 :         bbs_to_fix_dom.safe_push (dbb);
    9163              :     }
    9164              : 
    9165       195451 :   iterate_fix_dominators (CDI_DOMINATORS, bbs_to_fix_dom, true);
    9166              : 
    9167       195451 :   bbs_to_fix_dom.release ();
    9168       195451 : }
    9169              : 
    9170              : /* Purge dead EH edges from basic block BB.  */
    9171              : 
    9172              : bool
    9173    441996585 : gimple_purge_dead_eh_edges (basic_block bb)
    9174              : {
    9175    441996585 :   bool changed = false;
    9176    441996585 :   edge e;
    9177    441996585 :   edge_iterator ei;
    9178    441996585 :   gimple *stmt = *gsi_last_bb (bb);
    9179              : 
    9180    441996585 :   if (stmt && stmt_can_throw_internal (cfun, stmt))
    9181              :     return false;
    9182              : 
    9183    952030193 :   for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
    9184              :     {
    9185    552992416 :       if (e->flags & EDGE_EH)
    9186              :         {
    9187       959319 :           remove_edge_and_dominated_blocks (e);
    9188       959319 :           changed = true;
    9189              :         }
    9190              :       else
    9191    552033097 :         ei_next (&ei);
    9192              :     }
    9193              : 
    9194              :   return changed;
    9195              : }
    9196              : 
    9197              : /* Purge dead EH edges from basic block listed in BLOCKS.  */
    9198              : 
    9199              : bool
    9200      7460356 : gimple_purge_all_dead_eh_edges (const_bitmap blocks)
    9201              : {
    9202      7460356 :   bool changed = false;
    9203      7460356 :   unsigned i;
    9204      7460356 :   bitmap_iterator bi;
    9205              : 
    9206      7648961 :   EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i, bi)
    9207              :     {
    9208       188605 :       basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
    9209              : 
    9210              :       /* Earlier gimple_purge_dead_eh_edges could have removed
    9211              :          this basic block already.  */
    9212       188605 :       gcc_assert (bb || changed);
    9213       188605 :       if (bb != NULL)
    9214       188576 :         changed |= gimple_purge_dead_eh_edges (bb);
    9215              :     }
    9216              : 
    9217      7460356 :   return changed;
    9218              : }
    9219              : 
    9220              : /* Purge dead abnormal call edges from basic block BB.  */
    9221              : 
    9222              : bool
    9223     86286567 : gimple_purge_dead_abnormal_call_edges (basic_block bb)
    9224              : {
    9225     86286567 :   bool changed = false;
    9226     86286567 :   edge e;
    9227     86286567 :   edge_iterator ei;
    9228     86286567 :   gimple *stmt = *gsi_last_bb (bb);
    9229              : 
    9230     86286567 :   if (stmt && stmt_can_make_abnormal_goto (stmt))
    9231              :     return false;
    9232              : 
    9233    203449275 :   for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
    9234              :     {
    9235    117209884 :       if (e->flags & EDGE_ABNORMAL)
    9236              :         {
    9237         1418 :           if (e->flags & EDGE_FALLTHRU)
    9238            0 :             e->flags &= ~EDGE_ABNORMAL;
    9239              :           else
    9240         1418 :             remove_edge_and_dominated_blocks (e);
    9241    117209884 :           changed = true;
    9242              :         }
    9243              :       else
    9244    117208466 :         ei_next (&ei);
    9245              :     }
    9246              : 
    9247              :   return changed;
    9248              : }
    9249              : 
    9250              : /* Purge dead abnormal call edges from basic block listed in BLOCKS.  */
    9251              : 
    9252              : bool
    9253      7400855 : gimple_purge_all_dead_abnormal_call_edges (const_bitmap blocks)
    9254              : {
    9255      7400855 :   bool changed = false;
    9256      7400855 :   unsigned i;
    9257      7400855 :   bitmap_iterator bi;
    9258              : 
    9259      7400875 :   EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i, bi)
    9260              :     {
    9261           20 :       basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
    9262              : 
    9263              :       /* Earlier gimple_purge_dead_abnormal_call_edges could have removed
    9264              :          this basic block already.  */
    9265           20 :       gcc_assert (bb || changed);
    9266           20 :       if (bb != NULL)
    9267           20 :         changed |= gimple_purge_dead_abnormal_call_edges (bb);
    9268              :     }
    9269              : 
    9270      7400855 :   return changed;
    9271              : }
    9272              : 
    9273              : /* This function is called whenever a new edge is created or
    9274              :    redirected.  */
    9275              : 
    9276              : static void
    9277    163467680 : gimple_execute_on_growing_pred (edge e)
    9278              : {
    9279    163467680 :   basic_block bb = e->dest;
    9280              : 
    9281    163467680 :   if (!gimple_seq_empty_p (phi_nodes (bb)))
    9282     31285950 :     reserve_phi_args_for_new_edge (bb);
    9283    163467680 : }
    9284              : 
    9285              : /* This function is called immediately before edge E is removed from
    9286              :    the edge vector E->dest->preds.  */
    9287              : 
    9288              : static void
    9289    133704024 : gimple_execute_on_shrinking_pred (edge e)
    9290              : {
    9291    133704024 :   if (!gimple_seq_empty_p (phi_nodes (e->dest)))
    9292     35557611 :     remove_phi_args (e);
    9293    133704024 : }
    9294              : 
    9295              : /*---------------------------------------------------------------------------
    9296              :   Helper functions for Loop versioning
    9297              :   ---------------------------------------------------------------------------*/
    9298              : 
    9299              : /* Adjust phi nodes for 'first' basic block.  'second' basic block is a copy
    9300              :    of 'first'. Both of them are dominated by 'new_head' basic block. When
    9301              :    'new_head' was created by 'second's incoming edge it received phi arguments
    9302              :    on the edge by split_edge(). Later, additional edge 'e' was created to
    9303              :    connect 'new_head' and 'first'. Now this routine adds phi args on this
    9304              :    additional edge 'e' that new_head to second edge received as part of edge
    9305              :    splitting.  */
    9306              : 
    9307              : static void
    9308        39150 : gimple_lv_adjust_loop_header_phi (basic_block first, basic_block second,
    9309              :                                   basic_block new_head, edge e)
    9310              : {
    9311        39150 :   gphi *phi1, *phi2;
    9312        39150 :   gphi_iterator psi1, psi2;
    9313        39150 :   tree def;
    9314        39150 :   edge e2 = find_edge (new_head, second);
    9315              : 
    9316              :   /* Because NEW_HEAD has been created by splitting SECOND's incoming
    9317              :      edge, we should always have an edge from NEW_HEAD to SECOND.  */
    9318        39150 :   gcc_assert (e2 != NULL);
    9319              : 
    9320              :   /* Browse all 'second' basic block phi nodes and add phi args to
    9321              :      edge 'e' for 'first' head. PHI args are always in correct order.  */
    9322              : 
    9323        39150 :   for (psi2 = gsi_start_phis (second),
    9324        39150 :        psi1 = gsi_start_phis (first);
    9325       150001 :        !gsi_end_p (psi2) && !gsi_end_p (psi1);
    9326       110851 :        gsi_next (&psi2),  gsi_next (&psi1))
    9327              :     {
    9328       110851 :       phi1 = psi1.phi ();
    9329       110851 :       phi2 = psi2.phi ();
    9330       110851 :       def = PHI_ARG_DEF (phi2, e2->dest_idx);
    9331       110851 :       add_phi_arg (phi1, def, e, gimple_phi_arg_location_from_edge (phi2, e2));
    9332              :     }
    9333        39150 : }
    9334              : 
    9335              : 
    9336              : /* Adds a if else statement to COND_BB with condition COND_EXPR.
    9337              :    SECOND_HEAD is the destination of the THEN and FIRST_HEAD is
    9338              :    the destination of the ELSE part.  */
    9339              : 
    9340              : static void
    9341        39150 : gimple_lv_add_condition_to_bb (basic_block first_head ATTRIBUTE_UNUSED,
    9342              :                                basic_block second_head ATTRIBUTE_UNUSED,
    9343              :                                basic_block cond_bb, void *cond_e)
    9344              : {
    9345        39150 :   gimple_stmt_iterator gsi;
    9346        39150 :   gimple *new_cond_expr;
    9347        39150 :   tree cond_expr = (tree) cond_e;
    9348        39150 :   edge e0;
    9349              : 
    9350              :   /* Build new conditional expr */
    9351        39150 :   gsi = gsi_last_bb (cond_bb);
    9352              : 
    9353        39150 :   cond_expr = force_gimple_operand_gsi_1 (&gsi, cond_expr,
    9354              :                                           is_gimple_condexpr_for_cond,
    9355              :                                           NULL_TREE, false,
    9356              :                                           GSI_CONTINUE_LINKING);
    9357        39150 :   new_cond_expr = gimple_build_cond_from_tree (cond_expr,
    9358              :                                                NULL_TREE, NULL_TREE);
    9359              : 
    9360              :   /* Add new cond in cond_bb.  */
    9361        39150 :   gsi_insert_after (&gsi, new_cond_expr, GSI_NEW_STMT);
    9362              : 
    9363              :   /* Adjust edges appropriately to connect new head with first head
    9364              :      as well as second head.  */
    9365        39150 :   e0 = single_succ_edge (cond_bb);
    9366        39150 :   e0->flags &= ~EDGE_FALLTHRU;
    9367        39150 :   e0->flags |= EDGE_FALSE_VALUE;
    9368        39150 : }
    9369              : 
    9370              : 
    9371              : /* Do book-keeping of basic block BB for the profile consistency checker.
    9372              :    Store the counting in RECORD.  */
    9373              : static void
    9374            0 : gimple_account_profile_record (basic_block bb,
    9375              :                                struct profile_record *record)
    9376              : {
    9377            0 :   gimple_stmt_iterator i;
    9378            0 :   for (i = gsi_start_nondebug_after_labels_bb (bb); !gsi_end_p (i);
    9379            0 :        gsi_next_nondebug (&i))
    9380              :     {
    9381            0 :       record->size
    9382            0 :         += estimate_num_insns (gsi_stmt (i), &eni_size_weights);
    9383            0 :       if (profile_info)
    9384              :         {
    9385            0 :           if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.ipa ().initialized_p ()
    9386            0 :               && ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.ipa ().nonzero_p ()
    9387            0 :               && bb->count.ipa ().initialized_p ())
    9388            0 :             record->time
    9389            0 :               += estimate_num_insns (gsi_stmt (i),
    9390              :                                      &eni_time_weights)
    9391            0 :                                      * bb->count.ipa ().to_gcov_type ();
    9392              :         }
    9393            0 :       else if (bb->count.initialized_p ()
    9394            0 :                && ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.initialized_p ())
    9395            0 :         record->time
    9396            0 :           += estimate_num_insns
    9397            0 :                 (gsi_stmt (i),
    9398              :                  &eni_time_weights)
    9399            0 :                  * bb->count.to_sreal_scale
    9400            0 :                         (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count).to_double ();
    9401              :      else
    9402            0 :       record->time
    9403            0 :         += estimate_num_insns (gsi_stmt (i), &eni_time_weights);
    9404              :     }
    9405            0 : }
    9406              : 
    9407              : const struct cfg_hooks gimple_cfg_hooks = {
    9408              :   IR_GIMPLE,
    9409              :   gimple_verify_flow_info,
    9410              :   gimple_dump_bb,               /* dump_bb  */
    9411              :   gimple_dump_bb_for_graph,     /* dump_bb_for_graph  */
    9412              :   gimple_dump_bb_as_sarif_properties,
    9413              :   create_bb,                    /* create_basic_block  */
    9414              :   gimple_redirect_edge_and_branch, /* redirect_edge_and_branch  */
    9415              :   gimple_redirect_edge_and_branch_force, /* redirect_edge_and_branch_force  */
    9416              :   gimple_can_remove_branch_p,   /* can_remove_branch_p  */
    9417              :   remove_bb,                    /* delete_basic_block  */
    9418              :   gimple_split_block,           /* split_block  */
    9419              :   gimple_move_block_after,      /* move_block_after  */
    9420              :   gimple_can_merge_blocks_p,    /* can_merge_blocks_p  */
    9421              :   gimple_merge_blocks,          /* merge_blocks  */
    9422              :   gimple_predict_edge,          /* predict_edge  */
    9423              :   gimple_predicted_by_p,        /* predicted_by_p  */
    9424              :   gimple_can_duplicate_bb_p,    /* can_duplicate_block_p  */
    9425              :   gimple_duplicate_bb,          /* duplicate_block  */
    9426              :   gimple_split_edge,            /* split_edge  */
    9427              :   gimple_make_forwarder_block,  /* make_forward_block  */
    9428              :   NULL,                         /* tidy_fallthru_edge  */
    9429              :   NULL,                         /* force_nonfallthru */
    9430              :   gimple_block_ends_with_call_p,/* block_ends_with_call_p */
    9431              :   gimple_block_ends_with_condjump_p, /* block_ends_with_condjump_p */
    9432              :   gimple_flow_call_edges_add,   /* flow_call_edges_add */
    9433              :   gimple_execute_on_growing_pred,       /* execute_on_growing_pred */
    9434              :   gimple_execute_on_shrinking_pred, /* execute_on_shrinking_pred */
    9435              :   gimple_duplicate_loop_body_to_header_edge, /* duplicate loop for trees */
    9436              :   gimple_lv_add_condition_to_bb, /* lv_add_condition_to_bb */
    9437              :   gimple_lv_adjust_loop_header_phi, /* lv_adjust_loop_header_phi*/
    9438              :   extract_true_false_edges_from_block, /* extract_cond_bb_edges */
    9439              :   flush_pending_stmts,          /* flush_pending_stmts */
    9440              :   gimple_empty_block_p,           /* block_empty_p */
    9441              :   gimple_split_block_before_cond_jump, /* split_block_before_cond_jump */
    9442              :   gimple_account_profile_record,
    9443              : };
    9444              : 
    9445              : 
    9446              : /* Split all critical edges.  Split some extra (not necessarily critical) edges
    9447              :    if FOR_EDGE_INSERTION_P is true.  */
    9448              : 
    9449              : unsigned int
    9450      4305312 : split_critical_edges (bool for_edge_insertion_p /* = false */)
    9451              : {
    9452      4305312 :   basic_block bb;
    9453      4305312 :   edge e;
    9454      4305312 :   edge_iterator ei;
    9455              : 
    9456              :   /* split_edge can redirect edges out of SWITCH_EXPRs, which can get
    9457              :      expensive.  So we want to enable recording of edge to CASE_LABEL_EXPR
    9458              :      mappings around the calls to split_edge.  */
    9459      4305312 :   start_recording_case_labels ();
    9460     75879917 :   FOR_ALL_BB_FN (bb, cfun)
    9461              :     {
    9462    158851525 :       FOR_EACH_EDGE (e, ei, bb->succs)
    9463              :         {
    9464     87276920 :           if (EDGE_CRITICAL_P (e) && !(e->flags & EDGE_ABNORMAL))
    9465     15037021 :             split_edge (e);
    9466              :           /* PRE inserts statements to edges and expects that
    9467              :              since split_critical_edges was done beforehand, committing edge
    9468              :              insertions will not split more edges.  In addition to critical
    9469              :              edges we must split edges that have multiple successors and
    9470              :              end by control flow statements, such as RESX.
    9471              :              Go ahead and split them too.  This matches the logic in
    9472              :              gimple_find_edge_insert_loc.  */
    9473     72239899 :           else if (for_edge_insertion_p
    9474     56486100 :                    && (!single_pred_p (e->dest)
    9475     31521409 :                        || !gimple_seq_empty_p (phi_nodes (e->dest))
    9476     31281723 :                        || e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
    9477     28358740 :                    && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)
    9478    100598236 :                    && !(e->flags & EDGE_ABNORMAL))
    9479              :             {
    9480     28342608 :               gimple_stmt_iterator gsi;
    9481              : 
    9482     28342608 :               gsi = gsi_last_bb (e->src);
    9483     28342608 :               if (!gsi_end_p (gsi)
    9484     13983538 :                   && stmt_ends_bb_p (gsi_stmt (gsi))
    9485     31712890 :                   && (gimple_code (gsi_stmt (gsi)) != GIMPLE_RETURN
    9486       208463 :                       && !gimple_call_builtin_p (gsi_stmt (gsi),
    9487              :                                                  BUILT_IN_RETURN)))
    9488       207412 :                 split_edge (e);
    9489              :             }
    9490              :         }
    9491              :     }
    9492      4305312 :   end_recording_case_labels ();
    9493      4305312 :   return 0;
    9494              : }
    9495              : 
    9496              : namespace {
    9497              : 
    9498              : const pass_data pass_data_split_crit_edges =
    9499              : {
    9500              :   GIMPLE_PASS, /* type */
    9501              :   "crited", /* name */
    9502              :   OPTGROUP_NONE, /* optinfo_flags */
    9503              :   TV_TREE_SPLIT_EDGES, /* tv_id */
    9504              :   PROP_cfg, /* properties_required */
    9505              :   PROP_no_crit_edges, /* properties_provided */
    9506              :   0, /* properties_destroyed */
    9507              :   0, /* todo_flags_start */
    9508              :   0, /* todo_flags_finish */
    9509              : };
    9510              : 
    9511              : class pass_split_crit_edges : public gimple_opt_pass
    9512              : {
    9513              : public:
    9514       588392 :   pass_split_crit_edges (gcc::context *ctxt)
    9515      1176784 :     : gimple_opt_pass (pass_data_split_crit_edges, ctxt)
    9516              :   {}
    9517              : 
    9518              :   /* opt_pass methods: */
    9519      1062786 :   unsigned int execute (function *)  final override
    9520              :   {
    9521      1062786 :     return split_critical_edges ();
    9522              :   }
    9523              : 
    9524       294196 :   opt_pass * clone () final override
    9525              :   {
    9526       294196 :     return new pass_split_crit_edges (m_ctxt);
    9527              :   }
    9528              : }; // class pass_split_crit_edges
    9529              : 
    9530              : } // anon namespace
    9531              : 
    9532              : gimple_opt_pass *
    9533       294196 : make_pass_split_crit_edges (gcc::context *ctxt)
    9534              : {
    9535       294196 :   return new pass_split_crit_edges (ctxt);
    9536              : }
    9537              : 
    9538              : 
    9539              : /* Insert COND expression which is GIMPLE_COND after STMT
    9540              :    in basic block BB with appropriate basic block split
    9541              :    and creation of a new conditionally executed basic block.
    9542              :    Update profile so the new bb is visited with probability PROB.
    9543              :    Return created basic block.  */
    9544              : basic_block
    9545         2205 : insert_cond_bb (basic_block bb, gimple *stmt, gimple *cond,
    9546              :                 profile_probability prob)
    9547              : {
    9548         2205 :   edge fall = split_block (bb, stmt);
    9549         2205 :   gimple_stmt_iterator iter = gsi_last_bb (bb);
    9550         2205 :   basic_block new_bb;
    9551              : 
    9552              :   /* Insert cond statement.  */
    9553         2205 :   gcc_assert (gimple_code (cond) == GIMPLE_COND);
    9554         2205 :   if (gsi_end_p (iter))
    9555            0 :     gsi_insert_before (&iter, cond, GSI_CONTINUE_LINKING);
    9556              :   else
    9557         2205 :     gsi_insert_after (&iter, cond, GSI_CONTINUE_LINKING);
    9558              : 
    9559              :   /* Create conditionally executed block.  */
    9560         2205 :   new_bb = create_empty_bb (bb);
    9561         2205 :   if (coverage_suppressed_p (bb))
    9562            0 :     suppress_coverage (new_bb);
    9563         2205 :   edge e = make_edge (bb, new_bb, EDGE_TRUE_VALUE);
    9564         2205 :   e->probability = prob;
    9565         2205 :   new_bb->count = e->count ();
    9566         2205 :   make_single_succ_edge (new_bb, fall->dest, EDGE_FALLTHRU);
    9567              : 
    9568              :   /* Fix edge for split bb.  */
    9569         2205 :   fall->flags = EDGE_FALSE_VALUE;
    9570         2205 :   fall->probability -= e->probability;
    9571              : 
    9572              :   /* Update dominance info.  */
    9573         2205 :   if (dom_info_available_p (CDI_DOMINATORS))
    9574              :     {
    9575         2205 :       set_immediate_dominator (CDI_DOMINATORS, new_bb, bb);
    9576         2205 :       set_immediate_dominator (CDI_DOMINATORS, fall->dest, bb);
    9577              :     }
    9578              : 
    9579              :   /* Update loop info.  */
    9580         2205 :   if (current_loops)
    9581         2205 :     add_bb_to_loop (new_bb, bb->loop_father);
    9582              : 
    9583         2205 :   return new_bb;
    9584              : }
    9585              : 
    9586              : 
    9587              : 
    9588              : /* Given a basic block B which ends with a conditional and has
    9589              :    precisely two successors, determine which of the edges is taken if
    9590              :    the conditional is true and which is taken if the conditional is
    9591              :    false.  Set TRUE_EDGE and FALSE_EDGE appropriately.  */
    9592              : 
    9593              : void
    9594    857129120 : extract_true_false_edges_from_block (basic_block b,
    9595              :                                      edge *true_edge,
    9596              :                                      edge *false_edge)
    9597              : {
    9598    857129120 :   edge e = EDGE_SUCC (b, 0);
    9599              : 
    9600    857129120 :   if (e->flags & EDGE_TRUE_VALUE)
    9601              :     {
    9602    822247196 :       *true_edge = e;
    9603    822247196 :       *false_edge = EDGE_SUCC (b, 1);
    9604              :     }
    9605              :   else
    9606              :     {
    9607     34881924 :       *false_edge = e;
    9608     34881924 :       *true_edge = EDGE_SUCC (b, 1);
    9609              :     }
    9610    857129120 : }
    9611              : 
    9612              : 
    9613              : /* From a controlling predicate in the immediate dominator DOM of
    9614              :    PHIBLOCK determine the edges into PHIBLOCK that are chosen if the
    9615              :    predicate evaluates to true and false and store them to
    9616              :    *TRUE_CONTROLLED_EDGE and *FALSE_CONTROLLED_EDGE if
    9617              :    they are non-NULL.  Returns true if the edges can be determined,
    9618              :    else return false.  */
    9619              : 
    9620              : bool
    9621       143897 : extract_true_false_controlled_edges (basic_block dom, basic_block phiblock,
    9622              :                                      edge *true_controlled_edge,
    9623              :                                      edge *false_controlled_edge)
    9624              : {
    9625       143897 :   basic_block bb = phiblock;
    9626       143897 :   edge true_edge, false_edge, tem;
    9627       143897 :   edge e0 = NULL, e1 = NULL;
    9628              : 
    9629              :   /* We have to verify that one edge into the PHI node is dominated
    9630              :      by the true edge of the predicate block and the other edge
    9631              :      dominated by the false edge.  This ensures that the PHI argument
    9632              :      we are going to take is completely determined by the path we
    9633              :      take from the predicate block.
    9634              :      We can only use BB dominance checks below if the destination of
    9635              :      the true/false edges are dominated by their edge, thus only
    9636              :      have a single predecessor.  */
    9637       143897 :   extract_true_false_edges_from_block (dom, &true_edge, &false_edge);
    9638       143897 :   tem = EDGE_PRED (bb, 0);
    9639       143897 :   if (tem == true_edge
    9640       143897 :       || (single_pred_p (true_edge->dest)
    9641       105332 :           && (tem->src == true_edge->dest
    9642        65886 :               || dominated_by_p (CDI_DOMINATORS,
    9643              :                                  tem->src, true_edge->dest))))
    9644              :     e0 = tem;
    9645        58755 :   else if (tem == false_edge
    9646        58755 :            || (single_pred_p (false_edge->dest)
    9647        47671 :                && (tem->src == false_edge->dest
    9648        35306 :                    || dominated_by_p (CDI_DOMINATORS,
    9649              :                                       tem->src, false_edge->dest))))
    9650              :     e1 = tem;
    9651              :   else
    9652              :     return false;
    9653       118235 :   tem = EDGE_PRED (bb, 1);
    9654       118235 :   if (tem == true_edge
    9655       118235 :       || (single_pred_p (true_edge->dest)
    9656        85314 :           && (tem->src == true_edge->dest
    9657        67601 :               || dominated_by_p (CDI_DOMINATORS,
    9658              :                                  tem->src, true_edge->dest))))
    9659              :     e0 = tem;
    9660        88337 :   else if (tem == false_edge
    9661        88337 :            || (single_pred_p (false_edge->dest)
    9662        71280 :                && (tem->src == false_edge->dest
    9663        29733 :                    || dominated_by_p (CDI_DOMINATORS,
    9664              :                                       tem->src, false_edge->dest))))
    9665              :     e1 = tem;
    9666              :   else
    9667              :     return false;
    9668       107092 :   if (!e0 || !e1)
    9669              :     return false;
    9670              : 
    9671       107092 :   if (true_controlled_edge)
    9672       107092 :     *true_controlled_edge = e0;
    9673       107092 :   if (false_controlled_edge)
    9674       107092 :     *false_controlled_edge = e1;
    9675              : 
    9676              :   return true;
    9677              : }
    9678              : 
    9679              : /* Generate a range test LHS CODE RHS that determines whether INDEX is in the
    9680              :     range [low, high].  Place associated stmts before *GSI.  */
    9681              : 
    9682              : void
    9683         4498 : generate_range_test (basic_block bb, tree index, tree low, tree high,
    9684              :                      tree *lhs, tree *rhs)
    9685              : {
    9686         4498 :   tree type = TREE_TYPE (index);
    9687         4498 :   tree utype = range_check_type (type);
    9688              : 
    9689         4498 :   low = fold_convert (utype, low);
    9690         4498 :   high = fold_convert (utype, high);
    9691              : 
    9692         4498 :   gimple_seq seq = NULL;
    9693         4498 :   index = gimple_convert (&seq, utype, index);
    9694         4498 :   *lhs = gimple_build (&seq, MINUS_EXPR, utype, index, low);
    9695         4498 :   *rhs = const_binop (MINUS_EXPR, utype, high, low);
    9696              : 
    9697         4498 :   gimple_stmt_iterator gsi = gsi_last_bb (bb);
    9698         4498 :   gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
    9699         4498 : }
    9700              : 
    9701              : /* Return the basic block that belongs to label numbered INDEX
    9702              :    of a switch statement.  */
    9703              : 
    9704              : basic_block
    9705     60399399 : gimple_switch_label_bb (function *ifun, gswitch *gs, unsigned index)
    9706              : {
    9707     60399399 :   return label_to_block (ifun, CASE_LABEL (gimple_switch_label (gs, index)));
    9708              : }
    9709              : 
    9710              : /* Return the default basic block of a switch statement.  */
    9711              : 
    9712              : basic_block
    9713       337204 : gimple_switch_default_bb (function *ifun, gswitch *gs)
    9714              : {
    9715       337204 :   return gimple_switch_label_bb (ifun, gs, 0);
    9716              : }
    9717              : 
    9718              : /* Return the edge that belongs to label numbered INDEX
    9719              :    of a switch statement.  */
    9720              : 
    9721              : edge
    9722      1316662 : gimple_switch_edge (function *ifun, gswitch *gs, unsigned index)
    9723              : {
    9724      1316662 :   return find_edge (gimple_bb (gs), gimple_switch_label_bb (ifun, gs, index));
    9725              : }
    9726              : 
    9727              : /* Return the default edge of a switch statement.  */
    9728              : 
    9729              : edge
    9730       165319 : gimple_switch_default_edge (function *ifun, gswitch *gs)
    9731              : {
    9732       165319 :   return gimple_switch_edge (ifun, gs, 0);
    9733              : }
    9734              : 
    9735              : /* Return true if the only executable statement in BB is a GIMPLE_COND.  */
    9736              : 
    9737              : bool
    9738        13746 : cond_only_block_p (basic_block bb)
    9739              : {
    9740              :   /* BB must have no executable statements.  */
    9741        13746 :   gimple_stmt_iterator gsi = gsi_after_labels (bb);
    9742        13746 :   if (phi_nodes (bb))
    9743              :     return false;
    9744        31021 :   while (!gsi_end_p (gsi))
    9745              :     {
    9746        18012 :       gimple *stmt = gsi_stmt (gsi);
    9747        18012 :       if (is_gimple_debug (stmt))
    9748              :         ;
    9749        13746 :       else if (gimple_code (stmt) == GIMPLE_NOP
    9750              :                || gimple_code (stmt) == GIMPLE_PREDICT
    9751              :                || gimple_code (stmt) == GIMPLE_COND)
    9752              :         ;
    9753              :       else
    9754              :         return false;
    9755        17275 :       gsi_next (&gsi);
    9756              :     }
    9757              :   return true;
    9758              : }
    9759              : 
    9760              : 
    9761              : /* Emit return warnings.  */
    9762              : 
    9763              : namespace {
    9764              : 
    9765              : const pass_data pass_data_warn_function_return =
    9766              : {
    9767              :   GIMPLE_PASS, /* type */
    9768              :   "*warn_function_return", /* name */
    9769              :   OPTGROUP_NONE, /* optinfo_flags */
    9770              :   TV_NONE, /* tv_id */
    9771              :   PROP_cfg, /* properties_required */
    9772              :   0, /* properties_provided */
    9773              :   0, /* properties_destroyed */
    9774              :   0, /* todo_flags_start */
    9775              :   0, /* todo_flags_finish */
    9776              : };
    9777              : 
    9778              : class pass_warn_function_return : public gimple_opt_pass
    9779              : {
    9780              : public:
    9781       294196 :   pass_warn_function_return (gcc::context *ctxt)
    9782       588392 :     : gimple_opt_pass (pass_data_warn_function_return, ctxt)
    9783              :   {}
    9784              : 
    9785              :   /* opt_pass methods: */
    9786              :   unsigned int execute (function *) final override;
    9787              : 
    9788              : }; // class pass_warn_function_return
    9789              : 
    9790              : unsigned int
    9791      3027065 : pass_warn_function_return::execute (function *fun)
    9792              : {
    9793      3027065 :   location_t location;
    9794      3027065 :   gimple *last;
    9795      3027065 :   edge e;
    9796      3027065 :   edge_iterator ei;
    9797              : 
    9798      3027065 :   if (!targetm.warn_func_return (fun->decl))
    9799              :     return 0;
    9800              : 
    9801              :   /* If we have a path to EXIT, then we do return.  */
    9802      3026991 :   if (TREE_THIS_VOLATILE (fun->decl)
    9803      3026991 :       && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) > 0)
    9804              :     {
    9805           90 :       location = UNKNOWN_LOCATION;
    9806           90 :       for (ei = ei_start (EXIT_BLOCK_PTR_FOR_FN (fun)->preds);
    9807          180 :            (e = ei_safe_edge (ei)); )
    9808              :         {
    9809           90 :           last = *gsi_last_bb (e->src);
    9810              :           /* Warn about __builtin_return .*/
    9811           90 :           if (gimple_call_builtin_p (last, BUILT_IN_RETURN)
    9812           90 :               && location == UNKNOWN_LOCATION)
    9813              :             {
    9814            1 :               location = LOCATION_LOCUS (gimple_location (last));
    9815            1 :               ei_next (&ei);
    9816              :             }
    9817              :           /* Replace return stmts in noreturn functions
    9818              :              with __builtin_unreachable () call.  */
    9819           89 :           else if (gimple_code (last) == GIMPLE_RETURN)
    9820              :             {
    9821           89 :               location_t loc = gimple_location (last);
    9822           89 :               if (location == UNKNOWN_LOCATION)
    9823           89 :                 location = LOCATION_LOCUS (loc);
    9824           89 :               gimple *new_stmt = gimple_build_builtin_unreachable (loc);
    9825           89 :               gimple_stmt_iterator gsi = gsi_for_stmt (last);
    9826           89 :               gsi_replace (&gsi, new_stmt, true);
    9827           89 :               remove_edge (e);
    9828              :             }
    9829              :           else
    9830            0 :             ei_next (&ei);
    9831              :         }
    9832           90 :       if (location == UNKNOWN_LOCATION)
    9833            2 :         location = cfun->function_end_locus;
    9834           90 :       warning_at (location, 0, "%<noreturn%> function does return");
    9835              :     }
    9836              : 
    9837              :   /* If we see "return;" in some basic block, then we do reach the end
    9838              :      without returning a value.  */
    9839      3026901 :   else if (warn_return_type > 0
    9840      2046091 :            && !warning_suppressed_p (fun->decl, OPT_Wreturn_type)
    9841      5069781 :            && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fun->decl))))
    9842              :     {
    9843      2160995 :       FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (fun)->preds)
    9844              :         {
    9845      3234118 :           greturn *return_stmt = dyn_cast <greturn *> (*gsi_last_bb (e->src));
    9846      1077954 :           if (return_stmt
    9847      1077954 :               && gimple_return_retval (return_stmt) == NULL
    9848           37 :               && !warning_suppressed_p (return_stmt, OPT_Wreturn_type))
    9849              :             {
    9850           16 :               location = gimple_location (return_stmt);
    9851           16 :               if (LOCATION_LOCUS (location) == UNKNOWN_LOCATION)
    9852            0 :                 location = fun->function_end_locus;
    9853           16 :               if (warning_at (location, OPT_Wreturn_type,
    9854              :                               "control reaches end of non-void function"))
    9855           14 :                 suppress_warning (fun->decl, OPT_Wreturn_type);
    9856              :               break;
    9857              :             }
    9858              :         }
    9859              :       /* The C++ FE turns fallthrough from the end of non-void function
    9860              :          into __builtin_unreachable () call with BUILTINS_LOCATION.
    9861              :          Recognize those as well as calls from ubsan_instrument_return.  */
    9862      1082921 :       basic_block bb;
    9863      1082921 :       if (!warning_suppressed_p (fun->decl, OPT_Wreturn_type))
    9864      5078356 :         FOR_EACH_BB_FN (bb, fun)
    9865      3995983 :           if (EDGE_COUNT (bb->succs) == 0)
    9866              :             {
    9867       192151 :               gimple *last = *gsi_last_bb (bb);
    9868       192151 :               const enum built_in_function ubsan_missing_ret
    9869              :                 = BUILT_IN_UBSAN_HANDLE_MISSING_RETURN;
    9870       192151 :               if (last
    9871       192151 :                   && ((LOCATION_LOCUS (gimple_location (last))
    9872              :                        == BUILTINS_LOCATION
    9873          519 :                        && (gimple_call_builtin_p (last, BUILT_IN_UNREACHABLE)
    9874          190 :                            || gimple_call_builtin_p (last,
    9875              :                                                      BUILT_IN_UNREACHABLE_TRAP)
    9876            3 :                            || gimple_call_builtin_p (last, BUILT_IN_TRAP)))
    9877       191632 :                       || gimple_call_builtin_p (last, ubsan_missing_ret)))
    9878              :                 {
    9879          534 :                   gimple_stmt_iterator gsi = gsi_for_stmt (last);
    9880          534 :                   gsi_prev_nondebug (&gsi);
    9881          534 :                   gimple *prev = gsi_stmt (gsi);
    9882          534 :                   if (prev == NULL)
    9883              :                     location = UNKNOWN_LOCATION;
    9884              :                   else
    9885          186 :                     location = gimple_location (prev);
    9886          534 :                   if (LOCATION_LOCUS (location) == UNKNOWN_LOCATION)
    9887          374 :                     location = fun->function_end_locus;
    9888          534 :                   if (warning_at (location, OPT_Wreturn_type,
    9889              :                                   "control reaches end of non-void function"))
    9890          123 :                     suppress_warning (fun->decl, OPT_Wreturn_type);
    9891          534 :                   break;
    9892              :                 }
    9893              :             }
    9894              :     }
    9895              :   return 0;
    9896              : }
    9897              : 
    9898              : } // anon namespace
    9899              : 
    9900              : gimple_opt_pass *
    9901       294196 : make_pass_warn_function_return (gcc::context *ctxt)
    9902              : {
    9903       294196 :   return new pass_warn_function_return (ctxt);
    9904              : }
    9905              : 
    9906              : /* Walk a gimplified function and warn for functions whose return value is
    9907              :    ignored and attribute((warn_unused_result)) is set.  This is done before
    9908              :    inlining, so we don't have to worry about that.  */
    9909              : 
    9910              : static void
    9911     10385338 : do_warn_unused_result (gimple_seq seq)
    9912              : {
    9913     10385338 :   tree fdecl, ftype;
    9914     10385338 :   gimple_stmt_iterator i;
    9915              : 
    9916     64095567 :   for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
    9917              :     {
    9918     53710229 :       gimple *g = gsi_stmt (i);
    9919              : 
    9920     53710229 :       switch (gimple_code (g))
    9921              :         {
    9922      3658271 :         case GIMPLE_BIND:
    9923      3658271 :           do_warn_unused_result (gimple_bind_body (as_a <gbind *>(g)));
    9924      3658271 :           break;
    9925      2101580 :         case GIMPLE_TRY:
    9926      2101580 :           do_warn_unused_result (gimple_try_eval (g));
    9927      2101580 :           do_warn_unused_result (gimple_try_cleanup (g));
    9928      2101580 :           break;
    9929        21329 :         case GIMPLE_CATCH:
    9930        42658 :           do_warn_unused_result (gimple_catch_handler (
    9931        21329 :                                    as_a <gcatch *> (g)));
    9932        21329 :           break;
    9933         5891 :         case GIMPLE_EH_FILTER:
    9934         5891 :           do_warn_unused_result (gimple_eh_filter_failure (g));
    9935         5891 :           break;
    9936              : 
    9937      8117998 :         case GIMPLE_CALL:
    9938      8117998 :           if (gimple_call_lhs (g))
    9939              :             break;
    9940      4485836 :           if (gimple_call_internal_p (g))
    9941              :             break;
    9942      4463273 :           if (warning_suppressed_p (g, OPT_Wunused_result))
    9943              :             break;
    9944              : 
    9945              :           /* This is a naked call, as opposed to a GIMPLE_CALL with an
    9946              :              LHS.  All calls whose value is ignored should be
    9947              :              represented like this.  Look for the attribute.  */
    9948      4421197 :           fdecl = gimple_call_fndecl (g);
    9949      4421197 :           ftype = gimple_call_fntype (g);
    9950              : 
    9951      4421197 :           if (lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (ftype)))
    9952              :             {
    9953          186 :               auto_urlify_attributes sentinel;
    9954              : 
    9955          186 :               location_t loc = gimple_location (g);
    9956              : 
    9957          186 :               if (fdecl)
    9958          114 :                 warning_at (loc, OPT_Wunused_result,
    9959              :                             "ignoring return value of %qD "
    9960              :                             "declared with attribute %<warn_unused_result%>",
    9961              :                             fdecl);
    9962              :               else
    9963           72 :                 warning_at (loc, OPT_Wunused_result,
    9964              :                             "ignoring return value of function "
    9965              :                             "declared with attribute %<warn_unused_result%>");
    9966          186 :             }
    9967              :           break;
    9968              : 
    9969              :         default:
    9970              :           /* Not a container, not a call, or a call whose value is used.  */
    9971              :           break;
    9972              :         }
    9973              :     }
    9974     10385338 : }
    9975              : 
    9976              : namespace {
    9977              : 
    9978              : const pass_data pass_data_warn_unused_result =
    9979              : {
    9980              :   GIMPLE_PASS, /* type */
    9981              :   "*warn_unused_result", /* name */
    9982              :   OPTGROUP_NONE, /* optinfo_flags */
    9983              :   TV_NONE, /* tv_id */
    9984              :   PROP_gimple_any, /* properties_required */
    9985              :   0, /* properties_provided */
    9986              :   0, /* properties_destroyed */
    9987              :   0, /* todo_flags_start */
    9988              :   0, /* todo_flags_finish */
    9989              : };
    9990              : 
    9991              : class pass_warn_unused_result : public gimple_opt_pass
    9992              : {
    9993              : public:
    9994       294196 :   pass_warn_unused_result (gcc::context *ctxt)
    9995       588392 :     : gimple_opt_pass (pass_data_warn_unused_result, ctxt)
    9996              :   {}
    9997              : 
    9998              :   /* opt_pass methods: */
    9999      3027089 :   bool gate (function *)  final override { return flag_warn_unused_result; }
   10000      2496687 :   unsigned int execute (function *) final override
   10001              :     {
   10002      2496687 :       do_warn_unused_result (gimple_body (current_function_decl));
   10003      2496687 :       return 0;
   10004              :     }
   10005              : 
   10006              : }; // class pass_warn_unused_result
   10007              : 
   10008              : } // anon namespace
   10009              : 
   10010              : gimple_opt_pass *
   10011       294196 : make_pass_warn_unused_result (gcc::context *ctxt)
   10012              : {
   10013       294196 :   return new pass_warn_unused_result (ctxt);
   10014              : }
   10015              : 
   10016              : /* Maybe Remove stores to variables we marked write-only.
   10017              :    Return true if a store was removed. */
   10018              : static bool
   10019    474797601 : maybe_remove_writeonly_store (gimple_stmt_iterator &gsi, gimple *stmt,
   10020              :                               bitmap dce_ssa_names)
   10021              : {
   10022              :   /* Keep access when store has side effect, i.e. in case when source
   10023              :      is volatile.  */
   10024    474797601 :   if (!gimple_store_p (stmt)
   10025     64019387 :       || gimple_has_side_effects (stmt)
   10026    526465536 :       || optimize_debug)
   10027              :     return false;
   10028              : 
   10029     51616212 :   tree lhs = get_base_address (gimple_get_lhs (stmt));
   10030              : 
   10031     51616212 :   if (!VAR_P (lhs)
   10032     40474346 :       || (!TREE_STATIC (lhs) && !DECL_EXTERNAL (lhs))
   10033     58626095 :       || !varpool_node::get (lhs)->writeonly)
   10034              :     return false;
   10035              : 
   10036        30497 :   if (dump_file && (dump_flags & TDF_DETAILS))
   10037              :     {
   10038            0 :       fprintf (dump_file, "Removing statement, writes"
   10039              :                " to write only var:\n");
   10040            0 :       print_gimple_stmt (dump_file, stmt, 0,
   10041              :                          TDF_VOPS|TDF_MEMSYMS);
   10042              :     }
   10043              : 
   10044              :   /* Mark ssa name defining to be checked for simple dce. */
   10045        30497 :   if (gimple_assign_single_p (stmt))
   10046              :     {
   10047        30497 :       tree rhs = gimple_assign_rhs1 (stmt);
   10048        30497 :       if (TREE_CODE (rhs) == SSA_NAME
   10049        30497 :           && !SSA_NAME_IS_DEFAULT_DEF (rhs))
   10050         9636 :         bitmap_set_bit (dce_ssa_names, SSA_NAME_VERSION (rhs));
   10051              :     }
   10052        30497 :   unlink_stmt_vdef (stmt);
   10053        30497 :   gsi_remove (&gsi, true);
   10054        30497 :   release_defs (stmt);
   10055        30497 :   return true;
   10056              : }
   10057              : 
   10058              : /* IPA passes, compilation of earlier functions or inlining
   10059              :    might have changed some properties, such as marked functions nothrow,
   10060              :    pure, const or noreturn.
   10061              :    Remove redundant edges and basic blocks, and create new ones if necessary. */
   10062              : 
   10063              : unsigned int
   10064     11494154 : execute_fixup_cfg (void)
   10065              : {
   10066     11494154 :   basic_block bb;
   10067     11494154 :   gimple_stmt_iterator gsi;
   10068     11494154 :   int todo = 0;
   10069     11494154 :   cgraph_node *node = cgraph_node::get (current_function_decl);
   10070              :   /* Same scaling is also done by ipa_merge_profiles.  */
   10071     11494154 :   profile_count num = node->count;
   10072     11494154 :   profile_count den = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
   10073     11494154 :   bool scale = num.initialized_p () && !(num == den);
   10074     11494154 :   auto_bitmap dce_ssa_names;
   10075              : 
   10076     11494154 :   if (scale)
   10077              :     {
   10078        30211 :       profile_count::adjust_for_ipa_scaling (&num, &den);
   10079        30211 :       ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = node->count;
   10080        30211 :       EXIT_BLOCK_PTR_FOR_FN (cfun)->count
   10081        30211 :         = EXIT_BLOCK_PTR_FOR_FN (cfun)->count.apply_scale (num, den);
   10082              :     }
   10083              : 
   10084    102784570 :   FOR_EACH_BB_FN (bb, cfun)
   10085              :     {
   10086     91290416 :       if (scale)
   10087      1550059 :         bb->count = bb->count.apply_scale (num, den);
   10088    657378433 :       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
   10089              :         {
   10090    474797601 :           gimple *stmt = gsi_stmt (gsi);
   10091    474797601 :           tree decl = is_gimple_call (stmt)
   10092    474797601 :                       ? gimple_call_fndecl (stmt)
   10093              :                       : NULL;
   10094     45486612 :           if (decl)
   10095              :             {
   10096     42360626 :               int flags = gimple_call_flags (stmt);
   10097     42360626 :               if (flags & (ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE))
   10098              :                 {
   10099      7015740 :                   if (gimple_in_ssa_p (cfun))
   10100              :                     {
   10101      6313443 :                       todo |= TODO_update_ssa | TODO_cleanup_cfg;
   10102      6313443 :                       update_stmt (stmt);
   10103              :                     }
   10104              :                 }
   10105     42360626 :               if (flags & ECF_NORETURN
   10106     42360626 :                   && fixup_noreturn_call (stmt))
   10107        95281 :                 todo |= TODO_cleanup_cfg;
   10108              :              }
   10109              : 
   10110              :           /* Remove stores to variables we marked write-only. */
   10111    474797601 :           if (maybe_remove_writeonly_store (gsi, stmt, dce_ssa_names))
   10112              :             {
   10113        30497 :               todo |= TODO_update_ssa | TODO_cleanup_cfg;
   10114        30497 :               continue;
   10115              :             }
   10116              : 
   10117              :           /* For calls we can simply remove LHS when it is known
   10118              :              to be write-only.  */
   10119    474767104 :           if (is_gimple_call (stmt)
   10120    474767104 :               && gimple_get_lhs (stmt))
   10121              :             {
   10122     18670634 :               tree lhs = get_base_address (gimple_get_lhs (stmt));
   10123              : 
   10124     18670634 :               if (VAR_P (lhs)
   10125      4870017 :                   && (TREE_STATIC (lhs) || DECL_EXTERNAL (lhs))
   10126     18681154 :                   && varpool_node::get (lhs)->writeonly)
   10127              :                 {
   10128            2 :                   gimple_call_set_lhs (stmt, NULL);
   10129            2 :                   update_stmt (stmt);
   10130            2 :                   todo |= TODO_update_ssa | TODO_cleanup_cfg;
   10131              :                 }
   10132              :             }
   10133              : 
   10134    474767104 :           gsi_next (&gsi);
   10135              :         }
   10136    182580832 :       if (gimple *last = *gsi_last_bb (bb))
   10137              :         {
   10138     85138578 :           if (maybe_clean_eh_stmt (last)
   10139     85138578 :               && gimple_purge_dead_eh_edges (bb))
   10140       230881 :             todo |= TODO_cleanup_cfg;
   10141     85138578 :           if (gimple_purge_dead_abnormal_call_edges (bb))
   10142         1069 :             todo |= TODO_cleanup_cfg;
   10143              :         }
   10144              : 
   10145              :       /* If we have a basic block with no successors that does not
   10146              :          end with a control statement or a noreturn call end it with
   10147              :          a call to __builtin_unreachable.  This situation can occur
   10148              :          when inlining a noreturn call that does in fact return.  */
   10149     91290416 :       if (EDGE_COUNT (bb->succs) == 0)
   10150              :         {
   10151      6686960 :           gimple *stmt = last_nondebug_stmt (bb);
   10152      6686960 :           if (!stmt
   10153      6686960 :               || (!is_ctrl_stmt (stmt)
   10154      5802731 :                   && (!is_gimple_call (stmt)
   10155      5802713 :                       || !gimple_call_noreturn_p (stmt))))
   10156              :             {
   10157          132 :               if (stmt && is_gimple_call (stmt))
   10158          103 :                 gimple_call_set_ctrl_altering (stmt, false);
   10159          132 :               stmt = gimple_build_builtin_unreachable (UNKNOWN_LOCATION);
   10160          132 :               gimple_stmt_iterator gsi = gsi_last_bb (bb);
   10161          132 :               gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
   10162          132 :               if (!cfun->after_inlining)
   10163          108 :                 if (tree fndecl = gimple_call_fndecl (stmt))
   10164              :                   {
   10165          108 :                     gcall *call_stmt = dyn_cast <gcall *> (stmt);
   10166          108 :                     node->create_edge (cgraph_node::get_create (fndecl),
   10167              :                                        call_stmt, bb->count);
   10168              :                   }
   10169              :             }
   10170              :         }
   10171              :     }
   10172     11494154 :   if (scale)
   10173              :     {
   10174        30211 :       update_max_bb_count ();
   10175        30211 :       compute_function_frequency ();
   10176              :     }
   10177              : 
   10178     11494154 :   if (current_loops
   10179     11494154 :       && (todo & TODO_cleanup_cfg))
   10180      2026137 :     loops_state_set (LOOPS_NEED_FIXUP);
   10181              : 
   10182     11494154 :   simple_dce_from_worklist (dce_ssa_names);
   10183              : 
   10184     11494154 :   return todo;
   10185     11494154 : }
   10186              : 
   10187              : namespace {
   10188              : 
   10189              : const pass_data pass_data_fixup_cfg =
   10190              : {
   10191              :   GIMPLE_PASS, /* type */
   10192              :   "fixup_cfg", /* name */
   10193              :   OPTGROUP_NONE, /* optinfo_flags */
   10194              :   TV_NONE, /* tv_id */
   10195              :   PROP_cfg, /* properties_required */
   10196              :   0, /* properties_provided */
   10197              :   0, /* properties_destroyed */
   10198              :   0, /* todo_flags_start */
   10199              :   0, /* todo_flags_finish */
   10200              : };
   10201              : 
   10202              : class pass_fixup_cfg : public gimple_opt_pass
   10203              : {
   10204              : public:
   10205       882588 :   pass_fixup_cfg (gcc::context *ctxt)
   10206      1765176 :     : gimple_opt_pass (pass_data_fixup_cfg, ctxt)
   10207              :   {}
   10208              : 
   10209              :   /* opt_pass methods: */
   10210       588392 :   opt_pass * clone () final override { return new pass_fixup_cfg (m_ctxt); }
   10211      7523517 :   unsigned int execute (function *) final override
   10212              :   {
   10213      7523517 :     return execute_fixup_cfg ();
   10214              :   }
   10215              : 
   10216              : }; // class pass_fixup_cfg
   10217              : 
   10218              : } // anon namespace
   10219              : 
   10220              : gimple_opt_pass *
   10221       294196 : make_pass_fixup_cfg (gcc::context *ctxt)
   10222              : {
   10223       294196 :   return new pass_fixup_cfg (ctxt);
   10224              : }
   10225              : 
   10226              : 
   10227              : /* Sort PHI argument values for make_forwarders_with_degenerate_phis.  */
   10228              : 
   10229              : static int
   10230     47595013 : sort_phi_args (const void *a_, const void *b_)
   10231              : {
   10232     47595013 :   auto *a = (const std::pair<edge, hashval_t> *) a_;
   10233     47595013 :   auto *b = (const std::pair<edge, hashval_t> *) b_;
   10234     47595013 :   hashval_t ha = a->second;
   10235     47595013 :   hashval_t hb = b->second;
   10236     47595013 :   if (ha < hb)
   10237              :     return -1;
   10238     30082126 :   else if (ha > hb)
   10239              :     return 1;
   10240     15311314 :   else if (a->first->dest_idx < b->first->dest_idx)
   10241              :     return -1;
   10242      8003056 :   else if (a->first->dest_idx > b->first->dest_idx)
   10243              :     return 1;
   10244              :   else
   10245            0 :     return 0;
   10246              : }
   10247              : 
   10248              : /* Returns true if edge E comes from a possible ifconvertable branch.
   10249              :    That is:
   10250              :    ```
   10251              :    BB0:
   10252              :    if (a) goto BB1; else goto BB2;
   10253              :    BB1:
   10254              :    BB2:
   10255              :    ```
   10256              :    Returns true for the edge from BB0->BB2 or BB1->BB2.
   10257              :    This function assumes we only have one middle block.
   10258              :    And the middle block is empty. */
   10259              : 
   10260              : static bool
   10261      1245854 : ifconvertable_edge (edge e)
   10262              : {
   10263      1245854 :   basic_block bb2 = e->dest;
   10264      1245854 :   basic_block bb0 = e->src;
   10265      1245854 :   basic_block bb1 = nullptr, rbb1;
   10266      1245854 :   if (e->src == e->dest)
   10267              :     return false;
   10268      1245854 :   if (EDGE_COUNT (bb0->succs) > 2)
   10269              :     return false;
   10270      1239735 :   if (single_succ_p (bb0))
   10271              :     {
   10272       491756 :       if (!single_pred_p (bb0))
   10273              :         return false;
   10274              :       /* The middle block can only be empty,
   10275              :          otherwise the phis will be
   10276              :          different anyways. */
   10277       396927 :       if (!empty_block_p (bb0))
   10278              :         return false;
   10279        52186 :       bb1 = bb0;
   10280        52186 :       bb0 = single_pred (bb0);
   10281        52186 :       if (EDGE_COUNT (bb0->succs) != 2)
   10282              :         return false;
   10283              :     }
   10284              : 
   10285              :   /* If convertibles are only for conditionals. */
   10286       774434 :   if (!is_a<gcond*>(*gsi_last_nondebug_bb (bb0)))
   10287              :     return false;
   10288              : 
   10289              :   /* Find the other basic block.  */
   10290       712881 :   if (EDGE_SUCC (bb0, 0)->dest == bb2)
   10291       347686 :     rbb1 = EDGE_SUCC (bb0, 1)->dest;
   10292       365195 :   else if (EDGE_SUCC (bb0, 1)->dest == bb2)
   10293              :     rbb1 = EDGE_SUCC (bb0, 0)->dest;
   10294              :   else
   10295              :     return false;
   10296              : 
   10297              :   /* If we already know bb1, then just test it. */
   10298       712779 :   if (bb1)
   10299        26352 :     return rbb1 == bb1;
   10300              : 
   10301       893315 :   if (!single_succ_p (rbb1) || !single_pred_p (rbb1))
   10302              :     return false;
   10303              :   /* The middle block can only be empty,
   10304              :      otherwise the phis will be
   10305              :      different anyways. */
   10306       137121 :   if (!empty_block_p (rbb1))
   10307              :     return false;
   10308              : 
   10309        26352 :   return single_succ (rbb1) == bb2;
   10310              : }
   10311              : 
   10312              : /* Look for a non-virtual PHIs and make a forwarder block when all PHIs
   10313              :    have the same argument on a set of edges.  This is to not consider
   10314              :    control dependences of individual edges for same values but only for
   10315              :    the common set.  Returns true if changed the CFG.  */
   10316              : 
   10317              : bool
   10318      4705332 : make_forwarders_with_degenerate_phis (function *fn, bool skip_ifcvtable)
   10319              : {
   10320      4705332 :   bool didsomething = false;
   10321              : 
   10322      4705332 :   basic_block bb;
   10323     44817102 :   FOR_EACH_BB_FN (bb, fn)
   10324              :     {
   10325              :       /* Only PHIs with three or more arguments have opportunities.  */
   10326     40111770 :       if (EDGE_COUNT (bb->preds) < 3)
   10327     39635095 :         continue;
   10328              :       /* Do not touch loop headers or blocks with abnormal predecessors.
   10329              :          ???  This is to avoid creating valid loops here, see PR103458.
   10330              :          We might want to improve things to either explicitly add those
   10331              :          loops or at least consider blocks with no backedges.  */
   10332      1873889 :       if (bb->loop_father->header == bb
   10333      1870555 :           || bb_has_abnormal_pred (bb))
   10334         3334 :         continue;
   10335              : 
   10336              :       /* Take one PHI node as template to look for identical
   10337              :          arguments.  Build a vector of candidates forming sets
   10338              :          of argument edges with equal values.  Note optimality
   10339              :          depends on the particular choice of the template PHI
   10340              :          since equal arguments are unordered leaving other PHIs
   10341              :          with more than one set of equal arguments within this
   10342              :          argument range unsorted.  We'd have to break ties by
   10343              :          looking at other PHI nodes.  */
   10344      1867221 :       gphi_iterator gsi = gsi_start_nonvirtual_phis (bb);
   10345      1867221 :       if (gsi_end_p (gsi))
   10346      1077754 :         continue;
   10347       789467 :       gphi *phi = gsi.phi ();
   10348       789467 :       auto_vec<std::pair<edge, hashval_t>, 8> args;
   10349       789467 :       bool need_resort = false;
   10350      4754773 :       for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
   10351              :         {
   10352      3965306 :           edge e = gimple_phi_arg_edge (phi, i);
   10353              :           /* Skip abnormal edges since we cannot redirect them.  */
   10354      3965306 :           if (e->flags & EDGE_ABNORMAL)
   10355      3965306 :             continue;
   10356              :           /* Skip loop exit edges when we are in loop-closed SSA form
   10357              :              since the forwarder we'd create does not have a PHI node.  */
   10358      3965306 :           if (loops_state_satisfies_p (LOOP_CLOSED_SSA)
   10359      3965306 :               && loop_exit_edge_p (e->src->loop_father, e))
   10360        23236 :             continue;
   10361              : 
   10362              :           /* Skip ifconvertable edges when asked as we want the
   10363              :              copy/constant on that edge still when going out of ssa.
   10364              :              FIXME: phiopt should produce COND_EXPR but there
   10365              :              are regressions with that.  */
   10366      3942070 :           if (skip_ifcvtable && ifconvertable_edge (e))
   10367        52704 :             continue;
   10368              : 
   10369      3889366 :           tree arg = gimple_phi_arg_def (phi, i);
   10370      3889366 :           if (!CONSTANT_CLASS_P (arg) && TREE_CODE (arg) != SSA_NAME)
   10371      3889366 :             need_resort = true;
   10372      3889366 :           args.safe_push (std::make_pair (e, iterative_hash_expr (arg, 0)));
   10373              :         }
   10374       789467 :       if (args.length () < 2)
   10375        12860 :         continue;
   10376       776607 :       args.qsort (sort_phi_args);
   10377              :       /* The above sorting can be different between -g and -g0, as e.g. decls
   10378              :          can have different uids (-g could have bigger gaps in between them).
   10379              :          So, only use that to determine which args are equal, then change
   10380              :          second from hash value to smallest dest_idx of the edges which have
   10381              :          equal argument and sort again.  If all the phi arguments are
   10382              :          constants or SSA_NAME, there is no need for the second sort, the hash
   10383              :          values are stable in that case.  */
   10384       776607 :       hashval_t hash = args[0].second;
   10385       776607 :       args[0].second = args[0].first->dest_idx;
   10386       776607 :       bool any_equal = false;
   10387      3879048 :       for (unsigned i = 1; i < args.length (); ++i)
   10388      3102441 :         if (hash == args[i].second
   10389      4370336 :             && operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, args[i - 1].first),
   10390      1267895 :                                 PHI_ARG_DEF_FROM_EDGE (phi, args[i].first)))
   10391              :           {
   10392      1266664 :             args[i].second = args[i - 1].second;
   10393      1266664 :             any_equal = true;
   10394              :           }
   10395              :         else
   10396              :           {
   10397      1835777 :             hash = args[i].second;
   10398      1835777 :             args[i].second = args[i].first->dest_idx;
   10399              :           }
   10400       776607 :       if (!any_equal)
   10401       299932 :         continue;
   10402       476675 :       if (need_resort)
   10403        27698 :         args.qsort (sort_phi_args);
   10404              : 
   10405              :       /* From the candidates vector now verify true candidates for
   10406              :          forwarders and create them.  */
   10407       476675 :       gphi *vphi = get_virtual_phi (bb);
   10408       476675 :       unsigned start = 0;
   10409      3930175 :       while (start < args.length () - 1)
   10410              :         {
   10411      1252328 :           unsigned i;
   10412      3725563 :           for (i = start + 1; i < args.length (); ++i)
   10413      3473430 :             if (args[start].second != args[i].second)
   10414              :               break;
   10415              :           /* args[start]..args[i-1] are equal.  */
   10416      1252328 :           if (start != i - 1)
   10417              :             {
   10418              :               /* Check all PHI nodes for argument equality
   10419              :                  except for vops.  */
   10420       730489 :               bool equal = true;
   10421       730489 :               gphi_iterator gsi2 = gsi;
   10422       730489 :               gsi_next (&gsi2);
   10423      1570780 :               for (; !gsi_end_p (gsi2); gsi_next (&gsi2))
   10424              :                 {
   10425      1084894 :                   gphi *phi2 = gsi2.phi ();
   10426      2169788 :                   if (virtual_operand_p (gimple_phi_result (phi2)))
   10427       254226 :                     continue;
   10428       830668 :                   tree start_arg
   10429       830668 :                     = PHI_ARG_DEF_FROM_EDGE (phi2, args[start].first);
   10430      4411292 :                   for (unsigned j = start + 1; j < i; ++j)
   10431              :                     {
   10432      6094530 :                       if (!operand_equal_p (start_arg,
   10433      3047265 :                                             PHI_ARG_DEF_FROM_EDGE
   10434              :                                               (phi2, args[j].first)))
   10435              :                         {
   10436              :                           /* Another PHI might have a shorter set of
   10437              :                              equivalent args.  Go for that.  */
   10438       297309 :                           i = j;
   10439       297309 :                           if (j == start + 1)
   10440              :                             equal = false;
   10441              :                           break;
   10442              :                         }
   10443              :                     }
   10444              :                   if (!equal)
   10445              :                     break;
   10446              :                 }
   10447       730489 :               if (equal)
   10448              :                 {
   10449              :                   /* If we are asked to forward all edges the block
   10450              :                      has all degenerate PHIs.  Do nothing in that case.  */
   10451       485886 :                   if (start == 0
   10452       229732 :                       && i == args.length ()
   10453       489803 :                       && args.length () == gimple_phi_num_args (phi))
   10454              :                     break;
   10455              :                   /* Instead of using make_forwarder_block we are
   10456              :                      rolling our own variant knowing that the forwarder
   10457              :                      does not need PHI nodes apart from eventually
   10458              :                      a virtual one.  */
   10459       483633 :                   auto_vec<tree, 8> vphi_args;
   10460       483633 :                   if (vphi)
   10461              :                     {
   10462       324552 :                       vphi_args.reserve_exact (i - start);
   10463      1641611 :                       for (unsigned j = start; j < i; ++j)
   10464       992507 :                         vphi_args.quick_push
   10465       992507 :                           (PHI_ARG_DEF_FROM_EDGE (vphi, args[j].first));
   10466              :                     }
   10467       483633 :                   free_dominance_info (fn, CDI_DOMINATORS);
   10468       483633 :                   if (dump_file && (dump_flags & TDF_DETAILS))
   10469              :                     {
   10470            1 :                       fprintf (dump_file, "New forwarder block for edge ");
   10471            1 :                       fprintf (dump_file, "%d -> %d.\n",
   10472            1 :                                args[start].first->src->index,
   10473            1 :                                args[start].first->dest->index);
   10474              :                     }
   10475       483633 :                   basic_block forwarder = split_edge (args[start].first);
   10476       483633 :                   profile_count count = forwarder->count;
   10477       483633 :                   bool irr = false;
   10478      1488003 :                   for (unsigned j = start + 1; j < i; ++j)
   10479              :                     {
   10480      1004370 :                       edge e = args[j].first;
   10481      1004370 :                       if (e->flags & EDGE_IRREDUCIBLE_LOOP)
   10482         4678 :                         irr = true;
   10483      1004370 :                       redirect_edge_and_branch_force (e, forwarder);
   10484      1004370 :                       redirect_edge_var_map_clear (e);
   10485      1004370 :                       count += e->count ();
   10486              :                     }
   10487       483633 :                   forwarder->count = count;
   10488       483633 :                   if (irr)
   10489              :                     {
   10490         2990 :                       forwarder->flags |= BB_IRREDUCIBLE_LOOP;
   10491         2990 :                       single_succ_edge (forwarder)->flags
   10492         2990 :                         |= EDGE_IRREDUCIBLE_LOOP;
   10493              :                     }
   10494              : 
   10495       483633 :                   if (vphi)
   10496              :                     {
   10497       324552 :                       tree def = copy_ssa_name (vphi_args[0]);
   10498       324552 :                       gphi *vphi_copy = create_phi_node (def, forwarder);
   10499      1641611 :                       for (unsigned j = start; j < i; ++j)
   10500      1985014 :                         add_phi_arg (vphi_copy, vphi_args[j - start],
   10501       992507 :                                      args[j].first, UNKNOWN_LOCATION);
   10502       324552 :                       SET_PHI_ARG_DEF
   10503              :                         (vphi, single_succ_edge (forwarder)->dest_idx, def);
   10504              :                     }
   10505       483633 :                   didsomething = true;
   10506       483633 :                 }
   10507              :             }
   10508              :           /* Continue searching for more opportunities.  */
   10509      1250075 :           start = i;
   10510              :         }
   10511       789467 :     }
   10512      4705332 :   return didsomething;
   10513              : }
   10514              : 
   10515              : /* Garbage collection support for edge_def.  */
   10516              : 
   10517              : extern void gt_ggc_mx (tree&);
   10518              : extern void gt_ggc_mx (gimple *&);
   10519              : extern void gt_ggc_mx (rtx&);
   10520              : extern void gt_ggc_mx (basic_block&);
   10521              : 
   10522              : static void
   10523     48185004 : gt_ggc_mx (rtx_insn *& x)
   10524              : {
   10525            0 :   if (x)
   10526            0 :     gt_ggc_mx_rtx_def ((void *) x);
   10527            0 : }
   10528              : 
   10529              : void
   10530    160935999 : gt_ggc_mx (edge_def *e)
   10531              : {
   10532    160935999 :   tree block = LOCATION_BLOCK (e->goto_locus);
   10533    160935999 :   gt_ggc_mx (e->src);
   10534    160935999 :   gt_ggc_mx (e->dest);
   10535    160935999 :   if (current_ir_type () == IR_GIMPLE)
   10536    112750995 :     gt_ggc_mx (e->insns.g);
   10537              :   else
   10538     48185004 :     gt_ggc_mx (e->insns.r);
   10539    160935999 :   gt_ggc_mx (block);
   10540    160935999 : }
   10541              : 
   10542              : /* PCH support for edge_def.  */
   10543              : 
   10544              : extern void gt_pch_nx (tree&);
   10545              : extern void gt_pch_nx (gimple *&);
   10546              : extern void gt_pch_nx (rtx&);
   10547              : extern void gt_pch_nx (basic_block&);
   10548              : 
   10549              : static void
   10550            0 : gt_pch_nx (rtx_insn *& x)
   10551              : {
   10552            0 :   if (x)
   10553            0 :     gt_pch_nx_rtx_def ((void *) x);
   10554            0 : }
   10555              : 
   10556              : void
   10557            0 : gt_pch_nx (edge_def *e)
   10558              : {
   10559            0 :   tree block = LOCATION_BLOCK (e->goto_locus);
   10560            0 :   gt_pch_nx (e->src);
   10561            0 :   gt_pch_nx (e->dest);
   10562            0 :   if (current_ir_type () == IR_GIMPLE)
   10563            0 :     gt_pch_nx (e->insns.g);
   10564              :   else
   10565            0 :     gt_pch_nx (e->insns.r);
   10566            0 :   gt_pch_nx (block);
   10567            0 : }
   10568              : 
   10569              : void
   10570            0 : gt_pch_nx (edge_def *e, gt_pointer_operator op, void *cookie)
   10571              : {
   10572            0 :   tree block = LOCATION_BLOCK (e->goto_locus);
   10573            0 :   op (&(e->src), NULL, cookie);
   10574            0 :   op (&(e->dest), NULL, cookie);
   10575            0 :   if (current_ir_type () == IR_GIMPLE)
   10576            0 :     op (&(e->insns.g), NULL, cookie);
   10577              :   else
   10578            0 :     op (&(e->insns.r), NULL, cookie);
   10579            0 :   op (&(block), &(block), cookie);
   10580            0 : }
   10581              : 
   10582              : #if CHECKING_P
   10583              : 
   10584              : namespace selftest {
   10585              : 
   10586              : /* Helper function for CFG selftests: create a dummy function decl
   10587              :    and push it as cfun.  */
   10588              : 
   10589              : static tree
   10590           12 : push_fndecl (const char *name)
   10591              : {
   10592           12 :   tree fn_type = build_function_type_array (integer_type_node, 0, NULL);
   10593              :   /* FIXME: this uses input_location: */
   10594           12 :   tree fndecl = build_fn_decl (name, fn_type);
   10595           12 :   tree retval = build_decl (UNKNOWN_LOCATION, RESULT_DECL,
   10596              :                             NULL_TREE, integer_type_node);
   10597           12 :   DECL_RESULT (fndecl) = retval;
   10598           12 :   push_struct_function (fndecl);
   10599           12 :   function *fun = DECL_STRUCT_FUNCTION (fndecl);
   10600           12 :   ASSERT_TRUE (fun != NULL);
   10601           12 :   init_empty_tree_cfg_for_function (fun);
   10602           12 :   ASSERT_EQ (2, n_basic_blocks_for_fn (fun));
   10603           12 :   ASSERT_EQ (0, n_edges_for_fn (fun));
   10604           12 :   return fndecl;
   10605              : }
   10606              : 
   10607              : /* These tests directly create CFGs.
   10608              :    Compare with the static fns within tree-cfg.cc:
   10609              :      - build_gimple_cfg
   10610              :      - make_blocks: calls create_basic_block (seq, bb);
   10611              :      - make_edges.   */
   10612              : 
   10613              : /* Verify a simple cfg of the form:
   10614              :      ENTRY -> A -> B -> C -> EXIT.  */
   10615              : 
   10616              : static void
   10617            4 : test_linear_chain ()
   10618              : {
   10619            4 :   gimple_register_cfg_hooks ();
   10620              : 
   10621            4 :   tree fndecl = push_fndecl ("cfg_test_linear_chain");
   10622            4 :   function *fun = DECL_STRUCT_FUNCTION (fndecl);
   10623              : 
   10624              :   /* Create some empty blocks.  */
   10625            4 :   basic_block bb_a = create_empty_bb (ENTRY_BLOCK_PTR_FOR_FN (fun));
   10626            4 :   basic_block bb_b = create_empty_bb (bb_a);
   10627            4 :   basic_block bb_c = create_empty_bb (bb_b);
   10628              : 
   10629            4 :   ASSERT_EQ (5, n_basic_blocks_for_fn (fun));
   10630            4 :   ASSERT_EQ (0, n_edges_for_fn (fun));
   10631              : 
   10632              :   /* Create some edges: a simple linear chain of BBs.  */
   10633            4 :   make_edge (ENTRY_BLOCK_PTR_FOR_FN (fun), bb_a, EDGE_FALLTHRU);
   10634            4 :   make_edge (bb_a, bb_b, 0);
   10635            4 :   make_edge (bb_b, bb_c, 0);
   10636            4 :   make_edge (bb_c, EXIT_BLOCK_PTR_FOR_FN (fun), 0);
   10637              : 
   10638              :   /* Verify the edges.  */
   10639            4 :   ASSERT_EQ (4, n_edges_for_fn (fun));
   10640            4 :   ASSERT_EQ (NULL, ENTRY_BLOCK_PTR_FOR_FN (fun)->preds);
   10641            4 :   ASSERT_EQ (1, ENTRY_BLOCK_PTR_FOR_FN (fun)->succs->length ());
   10642            4 :   ASSERT_EQ (1, bb_a->preds->length ());
   10643            4 :   ASSERT_EQ (1, bb_a->succs->length ());
   10644            4 :   ASSERT_EQ (1, bb_b->preds->length ());
   10645            4 :   ASSERT_EQ (1, bb_b->succs->length ());
   10646            4 :   ASSERT_EQ (1, bb_c->preds->length ());
   10647            4 :   ASSERT_EQ (1, bb_c->succs->length ());
   10648            4 :   ASSERT_EQ (1, EXIT_BLOCK_PTR_FOR_FN (fun)->preds->length ());
   10649            4 :   ASSERT_EQ (NULL, EXIT_BLOCK_PTR_FOR_FN (fun)->succs);
   10650              : 
   10651              :   /* Verify the dominance information
   10652              :      Each BB in our simple chain should be dominated by the one before
   10653              :      it.  */
   10654            4 :   calculate_dominance_info (CDI_DOMINATORS);
   10655            4 :   ASSERT_EQ (bb_a, get_immediate_dominator (CDI_DOMINATORS, bb_b));
   10656            4 :   ASSERT_EQ (bb_b, get_immediate_dominator (CDI_DOMINATORS, bb_c));
   10657            4 :   auto_vec<basic_block> dom_by_b = get_dominated_by (CDI_DOMINATORS, bb_b);
   10658            4 :   ASSERT_EQ (1, dom_by_b.length ());
   10659            4 :   ASSERT_EQ (bb_c, dom_by_b[0]);
   10660            4 :   free_dominance_info (CDI_DOMINATORS);
   10661              : 
   10662              :   /* Similarly for post-dominance: each BB in our chain is post-dominated
   10663              :      by the one after it.  */
   10664            4 :   calculate_dominance_info (CDI_POST_DOMINATORS);
   10665            4 :   ASSERT_EQ (bb_b, get_immediate_dominator (CDI_POST_DOMINATORS, bb_a));
   10666            4 :   ASSERT_EQ (bb_c, get_immediate_dominator (CDI_POST_DOMINATORS, bb_b));
   10667            4 :   auto_vec<basic_block> postdom_by_b = get_dominated_by (CDI_POST_DOMINATORS, bb_b);
   10668            4 :   ASSERT_EQ (1, postdom_by_b.length ());
   10669            4 :   ASSERT_EQ (bb_a, postdom_by_b[0]);
   10670            4 :   free_dominance_info (CDI_POST_DOMINATORS);
   10671              : 
   10672            4 :   pop_cfun ();
   10673            4 : }
   10674              : 
   10675              : /* Verify a simple CFG of the form:
   10676              :      ENTRY
   10677              :        |
   10678              :        A
   10679              :       / \
   10680              :      /t  \f
   10681              :     B     C
   10682              :      \   /
   10683              :       \ /
   10684              :        D
   10685              :        |
   10686              :       EXIT.  */
   10687              : 
   10688              : static void
   10689            4 : test_diamond ()
   10690              : {
   10691            4 :   gimple_register_cfg_hooks ();
   10692              : 
   10693            4 :   tree fndecl = push_fndecl ("cfg_test_diamond");
   10694            4 :   function *fun = DECL_STRUCT_FUNCTION (fndecl);
   10695              : 
   10696              :   /* Create some empty blocks.  */
   10697            4 :   basic_block bb_a = create_empty_bb (ENTRY_BLOCK_PTR_FOR_FN (fun));
   10698            4 :   basic_block bb_b = create_empty_bb (bb_a);
   10699            4 :   basic_block bb_c = create_empty_bb (bb_a);
   10700            4 :   basic_block bb_d = create_empty_bb (bb_b);
   10701              : 
   10702            4 :   ASSERT_EQ (6, n_basic_blocks_for_fn (fun));
   10703            4 :   ASSERT_EQ (0, n_edges_for_fn (fun));
   10704              : 
   10705              :   /* Create the edges.  */
   10706            4 :   make_edge (ENTRY_BLOCK_PTR_FOR_FN (fun), bb_a, EDGE_FALLTHRU);
   10707            4 :   make_edge (bb_a, bb_b, EDGE_TRUE_VALUE);
   10708            4 :   make_edge (bb_a, bb_c, EDGE_FALSE_VALUE);
   10709            4 :   make_edge (bb_b, bb_d, 0);
   10710            4 :   make_edge (bb_c, bb_d, 0);
   10711            4 :   make_edge (bb_d, EXIT_BLOCK_PTR_FOR_FN (fun), 0);
   10712              : 
   10713              :   /* Verify the edges.  */
   10714            4 :   ASSERT_EQ (6, n_edges_for_fn (fun));
   10715            4 :   ASSERT_EQ (1, bb_a->preds->length ());
   10716            4 :   ASSERT_EQ (2, bb_a->succs->length ());
   10717            4 :   ASSERT_EQ (1, bb_b->preds->length ());
   10718            4 :   ASSERT_EQ (1, bb_b->succs->length ());
   10719            4 :   ASSERT_EQ (1, bb_c->preds->length ());
   10720            4 :   ASSERT_EQ (1, bb_c->succs->length ());
   10721            4 :   ASSERT_EQ (2, bb_d->preds->length ());
   10722            4 :   ASSERT_EQ (1, bb_d->succs->length ());
   10723              : 
   10724              :   /* Verify the dominance information.  */
   10725            4 :   calculate_dominance_info (CDI_DOMINATORS);
   10726            4 :   ASSERT_EQ (bb_a, get_immediate_dominator (CDI_DOMINATORS, bb_b));
   10727            4 :   ASSERT_EQ (bb_a, get_immediate_dominator (CDI_DOMINATORS, bb_c));
   10728            4 :   ASSERT_EQ (bb_a, get_immediate_dominator (CDI_DOMINATORS, bb_d));
   10729            4 :   auto_vec<basic_block> dom_by_a = get_dominated_by (CDI_DOMINATORS, bb_a);
   10730            4 :   ASSERT_EQ (3, dom_by_a.length ()); /* B, C, D, in some order.  */
   10731            4 :   dom_by_a.release ();
   10732            4 :   auto_vec<basic_block> dom_by_b = get_dominated_by (CDI_DOMINATORS, bb_b);
   10733            4 :   ASSERT_EQ (0, dom_by_b.length ());
   10734            4 :   dom_by_b.release ();
   10735            4 :   free_dominance_info (CDI_DOMINATORS);
   10736              : 
   10737              :   /* Similarly for post-dominance.  */
   10738            4 :   calculate_dominance_info (CDI_POST_DOMINATORS);
   10739            4 :   ASSERT_EQ (bb_d, get_immediate_dominator (CDI_POST_DOMINATORS, bb_a));
   10740            4 :   ASSERT_EQ (bb_d, get_immediate_dominator (CDI_POST_DOMINATORS, bb_b));
   10741            4 :   ASSERT_EQ (bb_d, get_immediate_dominator (CDI_POST_DOMINATORS, bb_c));
   10742            4 :   auto_vec<basic_block> postdom_by_d = get_dominated_by (CDI_POST_DOMINATORS, bb_d);
   10743            4 :   ASSERT_EQ (3, postdom_by_d.length ()); /* A, B, C in some order.  */
   10744            4 :   postdom_by_d.release ();
   10745            4 :   auto_vec<basic_block> postdom_by_b = get_dominated_by (CDI_POST_DOMINATORS, bb_b);
   10746            4 :   ASSERT_EQ (0, postdom_by_b.length ());
   10747            4 :   postdom_by_b.release ();
   10748            4 :   free_dominance_info (CDI_POST_DOMINATORS);
   10749              : 
   10750            4 :   pop_cfun ();
   10751            4 : }
   10752              : 
   10753              : /* Verify that we can handle a CFG containing a "complete" aka
   10754              :    fully-connected subgraph (where A B C D below all have edges
   10755              :    pointing to each other node, also to themselves).
   10756              :    e.g.:
   10757              :      ENTRY  EXIT
   10758              :        |    ^
   10759              :        |   /
   10760              :        |  /
   10761              :        | /
   10762              :        V/
   10763              :        A<--->B
   10764              :        ^^   ^^
   10765              :        | \ / |
   10766              :        |  X  |
   10767              :        | / \ |
   10768              :        VV   VV
   10769              :        C<--->D
   10770              : */
   10771              : 
   10772              : static void
   10773            4 : test_fully_connected ()
   10774              : {
   10775            4 :   gimple_register_cfg_hooks ();
   10776              : 
   10777            4 :   tree fndecl = push_fndecl ("cfg_fully_connected");
   10778            4 :   function *fun = DECL_STRUCT_FUNCTION (fndecl);
   10779              : 
   10780            4 :   const int n = 4;
   10781              : 
   10782              :   /* Create some empty blocks.  */
   10783            4 :   auto_vec <basic_block> subgraph_nodes;
   10784           20 :   for (int i = 0; i < n; i++)
   10785           16 :     subgraph_nodes.safe_push (create_empty_bb (ENTRY_BLOCK_PTR_FOR_FN (fun)));
   10786              : 
   10787            4 :   ASSERT_EQ (n + 2, n_basic_blocks_for_fn (fun));
   10788            4 :   ASSERT_EQ (0, n_edges_for_fn (fun));
   10789              : 
   10790              :   /* Create the edges.  */
   10791            4 :   make_edge (ENTRY_BLOCK_PTR_FOR_FN (fun), subgraph_nodes[0], EDGE_FALLTHRU);
   10792            4 :   make_edge (subgraph_nodes[0], EXIT_BLOCK_PTR_FOR_FN (fun), 0);
   10793           24 :   for (int i = 0; i < n; i++)
   10794           80 :     for (int j = 0; j < n; j++)
   10795           64 :       make_edge (subgraph_nodes[i], subgraph_nodes[j], 0);
   10796              : 
   10797              :   /* Verify the edges.  */
   10798            4 :   ASSERT_EQ (2 + (n * n), n_edges_for_fn (fun));
   10799              :   /* The first one is linked to ENTRY/EXIT as well as itself and
   10800              :      everything else.  */
   10801            4 :   ASSERT_EQ (n + 1, subgraph_nodes[0]->preds->length ());
   10802            4 :   ASSERT_EQ (n + 1, subgraph_nodes[0]->succs->length ());
   10803              :   /* The other ones in the subgraph are linked to everything in
   10804              :      the subgraph (including themselves).  */
   10805           16 :   for (int i = 1; i < n; i++)
   10806              :     {
   10807           12 :       ASSERT_EQ (n, subgraph_nodes[i]->preds->length ());
   10808           12 :       ASSERT_EQ (n, subgraph_nodes[i]->succs->length ());
   10809              :     }
   10810              : 
   10811              :   /* Verify the dominance information.  */
   10812            4 :   calculate_dominance_info (CDI_DOMINATORS);
   10813              :   /* The initial block in the subgraph should be dominated by ENTRY.  */
   10814            4 :   ASSERT_EQ (ENTRY_BLOCK_PTR_FOR_FN (fun),
   10815              :              get_immediate_dominator (CDI_DOMINATORS,
   10816              :                                       subgraph_nodes[0]));
   10817              :   /* Every other block in the subgraph should be dominated by the
   10818              :      initial block.  */
   10819           16 :   for (int i = 1; i < n; i++)
   10820           12 :     ASSERT_EQ (subgraph_nodes[0],
   10821              :                get_immediate_dominator (CDI_DOMINATORS,
   10822              :                                         subgraph_nodes[i]));
   10823            4 :   free_dominance_info (CDI_DOMINATORS);
   10824              : 
   10825              :   /* Similarly for post-dominance.  */
   10826            4 :   calculate_dominance_info (CDI_POST_DOMINATORS);
   10827              :   /* The initial block in the subgraph should be postdominated by EXIT.  */
   10828            4 :   ASSERT_EQ (EXIT_BLOCK_PTR_FOR_FN (fun),
   10829              :              get_immediate_dominator (CDI_POST_DOMINATORS,
   10830              :                                       subgraph_nodes[0]));
   10831              :   /* Every other block in the subgraph should be postdominated by the
   10832              :      initial block, since that leads to EXIT.  */
   10833           16 :   for (int i = 1; i < n; i++)
   10834           12 :     ASSERT_EQ (subgraph_nodes[0],
   10835              :                get_immediate_dominator (CDI_POST_DOMINATORS,
   10836              :                                         subgraph_nodes[i]));
   10837            4 :   free_dominance_info (CDI_POST_DOMINATORS);
   10838              : 
   10839            4 :   pop_cfun ();
   10840            4 : }
   10841              : 
   10842              : /* Run all of the selftests within this file.  */
   10843              : 
   10844              : void
   10845            4 : tree_cfg_cc_tests ()
   10846              : {
   10847            4 :   test_linear_chain ();
   10848            4 :   test_diamond ();
   10849            4 :   test_fully_connected ();
   10850            4 : }
   10851              : 
   10852              : } // namespace selftest
   10853              : 
   10854              : /* TODO: test the dominator/postdominator logic with various graphs/nodes:
   10855              :    - loop
   10856              :    - nested loops
   10857              :    - switch statement (a block with many out-edges)
   10858              :    - something that jumps to itself
   10859              :    - etc  */
   10860              : 
   10861              : #endif /* CHECKING_P */
        

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