LCOV - code coverage report
Current view: top level - gcc - tree-cfg.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 82.3 % 5164 4252
Test Date: 2026-09-19 16:22:48 Functions: 90.4 % 209 189
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.