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