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