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