LCOV - code coverage report
Current view: top level - gcc - cfgcleanup.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.0 % 1432 1332
Test Date: 2026-07-11 15:47:05 Functions: 100.0 % 39 39
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Control flow optimization code for GNU compiler.
       2              :    Copyright (C) 1987-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : /* This file contains optimizer of the control flow.  The main entry point is
      21              :    cleanup_cfg.  Following optimizations are performed:
      22              : 
      23              :    - Unreachable blocks removal
      24              :    - Edge forwarding (edge to the forwarder block is forwarded to its
      25              :      successor.  Simplification of the branch instruction is performed by
      26              :      underlying infrastructure so branch can be converted to simplejump or
      27              :      eliminated).
      28              :    - Cross jumping (tail merging)
      29              :    - Conditional jump-around-simplejump simplification
      30              :    - Basic block merging.  */
      31              : 
      32              : #include "config.h"
      33              : #include "system.h"
      34              : #include "coretypes.h"
      35              : #include "backend.h"
      36              : #include "target.h"
      37              : #include "rtl.h"
      38              : #include "tree.h"
      39              : #include "cfghooks.h"
      40              : #include "df.h"
      41              : #include "memmodel.h"
      42              : #include "tm_p.h"
      43              : #include "insn-config.h"
      44              : #include "emit-rtl.h"
      45              : #include "cselib.h"
      46              : #include "tree-pass.h"
      47              : #include "cfgloop.h"
      48              : #include "cfgrtl.h"
      49              : #include "cfganal.h"
      50              : #include "cfgbuild.h"
      51              : #include "cfgcleanup.h"
      52              : #include "dce.h"
      53              : #include "dbgcnt.h"
      54              : #include "rtl-iter.h"
      55              : #include "regs.h"
      56              : #include "function-abi.h"
      57              : 
      58              : #define FORWARDER_BLOCK_P(BB) ((BB)->flags & BB_FORWARDER_BLOCK)
      59              : 
      60              : /* Set to true when we are running first pass of try_optimize_cfg loop.  */
      61              : static bool first_pass;
      62              : 
      63              : /* Set to true if crossjumps occurred in the latest run of try_optimize_cfg.  */
      64              : static bool crossjumps_occurred;
      65              : 
      66              : /* Set to true if we couldn't run an optimization due to stale liveness
      67              :    information; we should run df_analyze to enable more opportunities.  */
      68              : static bool block_was_dirty;
      69              : 
      70              : static bool try_crossjump_to_edge (int, edge, edge, enum replace_direction);
      71              : static bool try_crossjump_bb (int, basic_block);
      72              : static bool outgoing_edges_match (int, basic_block, basic_block);
      73              : static enum replace_direction old_insns_match_p (int, rtx_insn *, rtx_insn *);
      74              : 
      75              : static void merge_blocks_move_predecessor_nojumps (basic_block, basic_block);
      76              : static void merge_blocks_move_successor_nojumps (basic_block, basic_block);
      77              : static bool try_optimize_cfg (int);
      78              : static bool try_simplify_condjump (basic_block);
      79              : static bool try_forward_edges (int, basic_block);
      80              : static edge thread_jump (edge, basic_block);
      81              : static bool mark_effect (rtx, bitmap);
      82              : static void notice_new_block (basic_block);
      83              : static void update_forwarder_flag (basic_block);
      84              : static void merge_memattrs (rtx, rtx);
      85              : 
      86              : /* Set flags for newly created block.  */
      87              : 
      88              : static void
      89        20936 : notice_new_block (basic_block bb)
      90              : {
      91        20936 :   if (!bb)
      92              :     return;
      93              : 
      94        14930 :   if (forwarder_block_p (bb))
      95        14930 :     bb->flags |= BB_FORWARDER_BLOCK;
      96              : }
      97              : 
      98              : /* Recompute forwarder flag after block has been modified.  */
      99              : 
     100              : static void
     101    315831854 : update_forwarder_flag (basic_block bb)
     102              : {
     103    315831854 :   if (forwarder_block_p (bb))
     104     16680042 :     bb->flags |= BB_FORWARDER_BLOCK;
     105              :   else
     106    299151812 :     bb->flags &= ~BB_FORWARDER_BLOCK;
     107    315831854 : }
     108              : 
     109              : /* Simplify a conditional jump around an unconditional jump.
     110              :    Return true if something changed.  */
     111              : 
     112              : static bool
     113     34685437 : try_simplify_condjump (basic_block cbranch_block)
     114              : {
     115     34685437 :   basic_block jump_block, jump_dest_block, cbranch_dest_block;
     116     34685437 :   edge cbranch_jump_edge, cbranch_fallthru_edge;
     117     34685437 :   rtx_insn *cbranch_insn;
     118              : 
     119              :   /* Verify that there are exactly two successors.  */
     120     34685437 :   if (EDGE_COUNT (cbranch_block->succs) != 2)
     121              :     return false;
     122              : 
     123              :   /* Verify that we've got a normal conditional branch at the end
     124              :      of the block.  */
     125     17401900 :   cbranch_insn = BB_END (cbranch_block);
     126     17401900 :   if (!any_condjump_p (cbranch_insn))
     127              :     return false;
     128              : 
     129     15262445 :   cbranch_fallthru_edge = FALLTHRU_EDGE (cbranch_block);
     130     15262445 :   cbranch_jump_edge = BRANCH_EDGE (cbranch_block);
     131              : 
     132              :   /* The next block must not have multiple predecessors, must not
     133              :      be the last block in the function, and must contain just the
     134              :      unconditional jump.  */
     135     15262445 :   jump_block = cbranch_fallthru_edge->dest;
     136     49940687 :   if (!single_pred_p (jump_block)
     137     13576409 :       || jump_block->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
     138     28674192 :       || !FORWARDER_BLOCK_P (jump_block))
     139              :     return false;
     140      1728105 :   jump_dest_block = single_succ (jump_block);
     141              : 
     142              :   /* If we are partitioning hot/cold basic blocks, we don't want to
     143              :      mess up unconditional or indirect jumps that cross between hot
     144              :      and cold sections.
     145              : 
     146              :      Basic block partitioning may result in some jumps that appear to
     147              :      be optimizable (or blocks that appear to be mergeable), but which really
     148              :      must be left untouched (they are required to make it safely across
     149              :      partition boundaries).  See the comments at the top of
     150              :      bb-reorder.cc:partition_hot_cold_basic_blocks for complete details.  */
     151              : 
     152      1728105 :   if (BB_PARTITION (jump_block) != BB_PARTITION (jump_dest_block)
     153      1688322 :       || (cbranch_jump_edge->flags & EDGE_CROSSING))
     154              :     return false;
     155              : 
     156              :   /* The conditional branch must target the block after the
     157              :      unconditional branch.  */
     158      1446208 :   cbranch_dest_block = cbranch_jump_edge->dest;
     159              : 
     160      1446208 :   if (cbranch_dest_block == EXIT_BLOCK_PTR_FOR_FN (cfun)
     161      1446208 :       || jump_dest_block == EXIT_BLOCK_PTR_FOR_FN (cfun)
     162      2891631 :       || !can_fallthru (jump_block, cbranch_dest_block))
     163      1439013 :     return false;
     164              : 
     165              :   /* Invert the conditional branch.  */
     166         7195 :   if (!invert_jump (as_a <rtx_jump_insn *> (cbranch_insn),
     167         7195 :                     block_label (jump_dest_block), 0))
     168              :     return false;
     169              : 
     170         7195 :   if (dump_file)
     171            1 :     fprintf (dump_file, "Simplifying condjump %i around jump %i\n",
     172            1 :              INSN_UID (cbranch_insn), INSN_UID (BB_END (jump_block)));
     173              : 
     174              :   /* Success.  Update the CFG to match.  Note that after this point
     175              :      the edge variable names appear backwards; the redirection is done
     176              :      this way to preserve edge profile data.  */
     177         7195 :   cbranch_jump_edge = redirect_edge_succ_nodup (cbranch_jump_edge,
     178              :                                                 cbranch_dest_block);
     179         7195 :   cbranch_fallthru_edge = redirect_edge_succ_nodup (cbranch_fallthru_edge,
     180              :                                                     jump_dest_block);
     181         7195 :   cbranch_jump_edge->flags |= EDGE_FALLTHRU;
     182         7195 :   cbranch_fallthru_edge->flags &= ~EDGE_FALLTHRU;
     183         7195 :   update_br_prob_note (cbranch_block);
     184              : 
     185              :   /* Delete the block with the unconditional jump, and clean up the mess.  */
     186         7195 :   delete_basic_block (jump_block);
     187         7195 :   tidy_fallthru_edge (cbranch_jump_edge);
     188         7195 :   update_forwarder_flag (cbranch_block);
     189              : 
     190         7195 :   return true;
     191              : }
     192              : 
     193              : /* Attempt to prove that operation is NOOP using CSElib or mark the effect
     194              :    on register.  Used by jump threading.  */
     195              : 
     196              : static bool
     197     33795852 : mark_effect (rtx exp, regset nonequal)
     198              : {
     199     33795852 :   rtx dest;
     200     33795852 :   switch (GET_CODE (exp))
     201              :     {
     202              :       /* In case we do clobber the register, mark it as equal, as we know the
     203              :          value is dead so it don't have to match.  */
     204      2472685 :     case CLOBBER:
     205      2472685 :       dest = XEXP (exp, 0);
     206      2472685 :       if (REG_P (dest))
     207      2441013 :         bitmap_clear_range (nonequal, REGNO (dest), REG_NREGS (dest));
     208              :       return false;
     209              : 
     210     11099895 :     case SET:
     211     11099895 :       if (cselib_redundant_set_p (exp))
     212              :         return false;
     213     10917248 :       dest = SET_DEST (exp);
     214     10917248 :       if (dest == pc_rtx)
     215              :         return false;
     216     10910057 :       if (!REG_P (dest))
     217              :         return true;
     218     10364121 :       bitmap_set_range (nonequal, REGNO (dest), REG_NREGS (dest));
     219     10364121 :       return false;
     220              : 
     221              :     default:
     222              :       return false;
     223              :     }
     224              : }
     225              : 
     226              : /* Return true if X contains a register in NONEQUAL.  */
     227              : static bool
     228      3601516 : mentions_nonequal_regs (const_rtx x, regset nonequal)
     229              : {
     230      3601516 :   subrtx_iterator::array_type array;
     231      7218378 :   FOR_EACH_SUBRTX (iter, array, x, NONCONST)
     232              :     {
     233      7211187 :       const_rtx x = *iter;
     234      7211187 :       if (REG_P (x))
     235              :         {
     236      3601757 :           unsigned int end_regno = END_REGNO (x);
     237      3609189 :           for (unsigned int regno = REGNO (x); regno < end_regno; ++regno)
     238      3601757 :             if (REGNO_REG_SET_P (nonequal, regno))
     239      3594325 :               return true;
     240              :         }
     241              :     }
     242         7191 :   return false;
     243      3601516 : }
     244              : 
     245              : /* Attempt to prove that the basic block B will have no side effects and
     246              :    always continues in the same edge if reached via E.  Return the edge
     247              :    if exist, NULL otherwise.  */
     248              : 
     249              : static edge
     250     28414924 : thread_jump (edge e, basic_block b)
     251              : {
     252     28414924 :   rtx set1, set2, cond1, cond2;
     253     28414924 :   rtx_insn *insn;
     254     28414924 :   enum rtx_code code1, code2, reversed_code2;
     255     28414924 :   bool reverse1 = false;
     256     28414924 :   unsigned i;
     257     28414924 :   regset nonequal;
     258     28414924 :   bool failed = false;
     259              : 
     260              :   /* Jump threading may cause fixup_partitions to introduce new crossing edges,
     261              :      which is not allowed after reload.  */
     262     28414924 :   gcc_checking_assert (!reload_completed || !crtl->has_bb_partition);
     263              : 
     264     28414924 :   if (b->flags & BB_NONTHREADABLE_BLOCK)
     265              :     return NULL;
     266              : 
     267              :   /* At the moment, we do handle only conditional jumps, but later we may
     268              :      want to extend this code to tablejumps and others.  */
     269     45577615 :   if (EDGE_COUNT (e->src->succs) != 2)
     270              :     return NULL;
     271     17169303 :   if (EDGE_COUNT (b->succs) != 2)
     272              :     {
     273      7580534 :       b->flags |= BB_NONTHREADABLE_BLOCK;
     274      7580534 :       return NULL;
     275              :     }
     276              : 
     277              :   /* Second branch must end with onlyjump, as we will eliminate the jump.  */
     278      9588769 :   if (!any_condjump_p (BB_END (e->src)))
     279              :     return NULL;
     280              : 
     281      8747151 :   if (!any_condjump_p (BB_END (b)) || !onlyjump_p (BB_END (b)))
     282              :     {
     283       649704 :       b->flags |= BB_NONTHREADABLE_BLOCK;
     284       649704 :       return NULL;
     285              :     }
     286              : 
     287      8097447 :   set1 = pc_set (BB_END (e->src));
     288      8097447 :   set2 = pc_set (BB_END (b));
     289      8097447 :   if (((e->flags & EDGE_FALLTHRU) != 0)
     290      8097447 :       != (XEXP (SET_SRC (set1), 1) == pc_rtx))
     291      4007446 :     reverse1 = true;
     292              : 
     293      8097447 :   cond1 = XEXP (SET_SRC (set1), 0);
     294      8097447 :   cond2 = XEXP (SET_SRC (set2), 0);
     295      8097447 :   if (reverse1)
     296      4007446 :     code1 = reversed_comparison_code (cond1, BB_END (e->src));
     297              :   else
     298      4090001 :     code1 = GET_CODE (cond1);
     299              : 
     300      8097447 :   code2 = GET_CODE (cond2);
     301      8097447 :   reversed_code2 = reversed_comparison_code (cond2, BB_END (b));
     302              : 
     303      8097447 :   if (!comparison_dominates_p (code1, code2)
     304      8097447 :       && !comparison_dominates_p (code1, reversed_code2))
     305              :     return NULL;
     306              : 
     307              :   /* Ensure that the comparison operators are equivalent.
     308              :      ??? This is far too pessimistic.  We should allow swapped operands,
     309              :      different CCmodes, or for example comparisons for interval, that
     310              :      dominate even when operands are not equivalent.  */
     311      6498370 :   if (!rtx_equal_p (XEXP (cond1, 0), XEXP (cond2, 0))
     312      6498370 :       || !rtx_equal_p (XEXP (cond1, 1), XEXP (cond2, 1)))
     313       928174 :     return NULL;
     314              : 
     315              :   /* Punt if BB_END (e->src) is doloop-like conditional jump that modifies
     316              :      the registers used in cond1.  */
     317      5570196 :   if (modified_in_p (cond1, BB_END (e->src)))
     318              :     return NULL;
     319              : 
     320              :   /* Short circuit cases where block B contains some side effects, as we can't
     321              :      safely bypass it.  */
     322     64337062 :   for (insn = NEXT_INSN (BB_HEAD (b)); insn != NEXT_INSN (BB_END (b));
     323     53196670 :        insn = NEXT_INSN (insn))
     324     54619414 :     if (INSN_P (insn) && side_effects_p (PATTERN (insn)))
     325              :       {
     326      1422744 :         b->flags |= BB_NONTHREADABLE_BLOCK;
     327      1422744 :         return NULL;
     328              :       }
     329              : 
     330      4147452 :   cselib_init (0);
     331              : 
     332              :   /* First process all values computed in the source basic block.  */
     333     59856184 :   for (insn = NEXT_INSN (BB_HEAD (e->src));
     334     59856184 :        insn != NEXT_INSN (BB_END (e->src));
     335     55708732 :        insn = NEXT_INSN (insn))
     336     55708732 :     if (INSN_P (insn))
     337     51983668 :       cselib_process_insn (insn);
     338              : 
     339      4147452 :   nonequal = BITMAP_ALLOC (NULL);
     340      4147452 :   CLEAR_REG_SET (nonequal);
     341              : 
     342              :   /* Now assume that we've continued by the edge E to B and continue
     343              :      processing as if it were same basic block.
     344              :      Our goal is to prove that whole block is an NOOP.  */
     345              : 
     346     38455647 :   for (insn = NEXT_INSN (BB_HEAD (b));
     347     38455647 :        insn != NEXT_INSN (BB_END (b)) && !failed;
     348     34308195 :        insn = NEXT_INSN (insn))
     349              :     {
     350              :       /* cond2 must not mention any register that is not equal to the
     351              :          former block.  Check this before processing that instruction,
     352              :          as BB_END (b) could contain also clobbers.  */
     353     37902520 :       if (insn == BB_END (b)
     354     37902520 :           && mentions_nonequal_regs (cond2, nonequal))
     355      3594325 :         goto failed_exit;
     356              : 
     357     34308195 :       if (INSN_P (insn))
     358              :         {
     359     31225153 :           rtx pat = PATTERN (insn);
     360              : 
     361     31225153 :           if (GET_CODE (pat) == PARALLEL)
     362              :             {
     363      7536549 :               for (i = 0; i < (unsigned)XVECLEN (pat, 0); i++)
     364      5053624 :                 failed |= mark_effect (XVECEXP (pat, 0, i), nonequal);
     365              :             }
     366              :           else
     367     28742228 :             failed |= mark_effect (pat, nonequal);
     368              :         }
     369              : 
     370     34308195 :       cselib_process_insn (insn);
     371              :     }
     372              : 
     373              :   /* Later we should clear nonequal of dead registers.  So far we don't
     374              :      have life information in cfg_cleanup.  */
     375       553127 :   if (failed)
     376              :     {
     377       545936 :       b->flags |= BB_NONTHREADABLE_BLOCK;
     378       545936 :       goto failed_exit;
     379              :     }
     380              : 
     381         7191 :   if (!REG_SET_EMPTY_P (nonequal))
     382          579 :     goto failed_exit;
     383              : 
     384         6612 :   BITMAP_FREE (nonequal);
     385         6612 :   cselib_finish ();
     386         6612 :   if ((comparison_dominates_p (code1, code2) != 0)
     387         6612 :       != (XEXP (SET_SRC (set2), 1) == pc_rtx))
     388         4413 :     return BRANCH_EDGE (b);
     389              :   else
     390         2199 :     return FALLTHRU_EDGE (b);
     391              : 
     392      4140840 : failed_exit:
     393      4140840 :   BITMAP_FREE (nonequal);
     394      4140840 :   cselib_finish ();
     395      4140840 :   return NULL;
     396              : }
     397              : 
     398              : /* Attempt to forward edges leaving basic block B.
     399              :    Return true if successful.  */
     400              : 
     401              : static bool
     402    404209576 : try_forward_edges (int mode, basic_block b)
     403              : {
     404    404209576 :   bool changed = false;
     405    404209576 :   edge_iterator ei;
     406    404209576 :   edge e, *threaded_edges = NULL;
     407              : 
     408   1012691689 :   for (ei = ei_start (b->succs); (e = ei_safe_edge (ei)); )
     409              :     {
     410    608482113 :       basic_block target, first;
     411    608482113 :       location_t goto_locus;
     412    608482113 :       int counter;
     413    608482113 :       bool threaded = false;
     414    608482113 :       int nthreaded_edges = 0;
     415    608482113 :       bool may_thread = first_pass || (b->flags & BB_MODIFIED) != 0;
     416    608482113 :       bool new_target_threaded = false;
     417              : 
     418              :       /* Skip complex edges because we don't know how to update them.
     419              : 
     420              :          Still handle fallthru edges, as we can succeed to forward fallthru
     421              :          edge to the same place as the branch edge of conditional branch
     422              :          and turn conditional branch to an unconditional branch.  */
     423    608482113 :       if (e->flags & EDGE_COMPLEX)
     424              :         {
     425     34233872 :           ei_next (&ei);
     426     34233872 :           continue;
     427              :         }
     428              : 
     429    574248241 :       target = first = e->dest;
     430    574248241 :       counter = NUM_FIXED_BLOCKS;
     431    574248241 :       goto_locus = e->goto_locus;
     432              : 
     433    603837934 :       while (counter < n_basic_blocks_for_fn (cfun))
     434              :         {
     435    603418746 :           basic_block new_target = NULL;
     436    603418746 :           may_thread |= (target->flags & BB_MODIFIED) != 0;
     437              : 
     438    603418746 :           if (FORWARDER_BLOCK_P (target)
     439    642475738 :               && single_succ (target) != EXIT_BLOCK_PTR_FOR_FN (cfun))
     440              :             {
     441              :               /* Bypass trivial infinite loops.  */
     442     29772359 :               new_target = single_succ (target);
     443     29772359 :               if (target == new_target)
     444              :                 counter = n_basic_blocks_for_fn (cfun);
     445     29491884 :               else if (!optimize)
     446              :                 {
     447              :                   /* When not optimizing, ensure that edges or forwarder
     448              :                      blocks with different locus are not optimized out.  */
     449      1189538 :                   location_t new_locus = single_succ_edge (target)->goto_locus;
     450      1189538 :                   location_t locus = goto_locus;
     451              : 
     452      1189538 :                   if (LOCATION_LOCUS (new_locus) != UNKNOWN_LOCATION
     453       474531 :                       && LOCATION_LOCUS (locus) != UNKNOWN_LOCATION
     454      1501188 :                       && new_locus != locus)
     455              :                     new_target = NULL;
     456              :                   else
     457              :                     {
     458      1009226 :                       if (LOCATION_LOCUS (new_locus) != UNKNOWN_LOCATION)
     459       294219 :                         locus = new_locus;
     460              : 
     461      1009226 :                       rtx_insn *last = BB_END (target);
     462      1009226 :                       if (DEBUG_INSN_P (last))
     463            6 :                         last = prev_nondebug_insn (last);
     464      1009226 :                       if (last && INSN_P (last))
     465       500162 :                         new_locus = INSN_LOCATION (last);
     466              :                       else
     467              :                         new_locus = UNKNOWN_LOCATION;
     468              : 
     469       500162 :                       if (LOCATION_LOCUS (new_locus) != UNKNOWN_LOCATION
     470       483418 :                           && LOCATION_LOCUS (locus) != UNKNOWN_LOCATION
     471      1378890 :                           && new_locus != locus)
     472              :                         new_target = NULL;
     473              :                       else
     474              :                         {
     475      1000799 :                           if (LOCATION_LOCUS (new_locus) != UNKNOWN_LOCATION)
     476       474991 :                             locus = new_locus;
     477              : 
     478              :                           goto_locus = locus;
     479              :                         }
     480              :                     }
     481              :                 }
     482              :             }
     483              : 
     484              :           /* Allow to thread only over one edge at time to simplify updating
     485              :              of probabilities.  */
     486    573646387 :           else if ((mode & CLEANUP_THREADING) && may_thread)
     487              :             {
     488     28414924 :               edge t = thread_jump (e, target);
     489     28414924 :               if (t)
     490              :                 {
     491         6612 :                   if (!threaded_edges)
     492         6543 :                     threaded_edges = XNEWVEC (edge,
     493              :                                               n_basic_blocks_for_fn (cfun));
     494              :                   else
     495              :                     {
     496              :                       int i;
     497              : 
     498              :                       /* Detect an infinite loop across blocks not
     499              :                          including the start block.  */
     500          216 :                       for (i = 0; i < nthreaded_edges; ++i)
     501          161 :                         if (threaded_edges[i] == t)
     502              :                           break;
     503           69 :                       if (i < nthreaded_edges)
     504              :                         {
     505           14 :                           counter = n_basic_blocks_for_fn (cfun);
     506           14 :                           break;
     507              :                         }
     508              :                     }
     509              : 
     510              :                   /* Detect an infinite loop across the start block.  */
     511         6598 :                   if (t->dest == b)
     512              :                     break;
     513              : 
     514         6073 :                   gcc_assert (nthreaded_edges
     515              :                               < (n_basic_blocks_for_fn (cfun)
     516              :                                  - NUM_FIXED_BLOCKS));
     517         6073 :                   threaded_edges[nthreaded_edges++] = t;
     518              : 
     519         6073 :                   new_target = t->dest;
     520         6073 :                   new_target_threaded = true;
     521              :                 }
     522              :             }
     523              : 
     524     29589693 :           if (!new_target)
     525              :             break;
     526              : 
     527     29589693 :           counter++;
     528              :           /* Do not turn non-crossing jump to crossing.  Depending on target
     529              :              it may require different instruction pattern.  */
     530     29589693 :           if ((e->flags & EDGE_CROSSING)
     531     29555720 :               || BB_PARTITION (first) == BB_PARTITION (new_target))
     532              :             {
     533     15372954 :               target = new_target;
     534     15372954 :               threaded |= new_target_threaded;
     535              :             }
     536              :         }
     537              : 
     538    574248241 :       if (counter >= n_basic_blocks_for_fn (cfun))
     539              :         {
     540       419202 :           if (dump_file)
     541            4 :             fprintf (dump_file, "Infinite loop in BB %i.\n",
     542              :                      target->index);
     543              :         }
     544    573829039 :       else if (target == first)
     545              :         ; /* We didn't do anything.  */
     546              :       else
     547              :         {
     548              :           /* Save the values now, as the edge may get removed.  */
     549     14178748 :           profile_count edge_count = e->count ();
     550     14178748 :           int n = 0;
     551              : 
     552     14178748 :           e->goto_locus = goto_locus;
     553              : 
     554              :           /* Don't force if target is exit block.  */
     555     14178748 :           if (threaded && target != EXIT_BLOCK_PTR_FOR_FN (cfun))
     556              :             {
     557         6006 :               notice_new_block (redirect_edge_and_branch_force (e, target));
     558         6006 :               if (dump_file)
     559            0 :                 fprintf (dump_file, "Conditionals threaded.\n");
     560              :             }
     561     14172742 :           else if (!redirect_edge_and_branch (e, target))
     562              :             {
     563      7599237 :               if (dump_file)
     564          187 :                 fprintf (dump_file,
     565              :                          "Forwarding edge %i->%i to %i failed.\n",
     566          187 :                          b->index, e->dest->index, target->index);
     567      7599237 :               ei_next (&ei);
     568      7599237 :               continue;
     569              :             }
     570              : 
     571              :           /* We successfully forwarded the edge.  Now update profile
     572              :              data: for each edge we traversed in the chain, remove
     573              :              the original edge's execution count.  */
     574      6688934 :           do
     575              :             {
     576      6688934 :               edge t;
     577              : 
     578      6688934 :               if (!single_succ_p (first))
     579              :                 {
     580         6059 :                   gcc_assert (n < nthreaded_edges);
     581         6059 :                   t = threaded_edges [n++];
     582         6059 :                   gcc_assert (t->src == first);
     583         6059 :                   update_bb_profile_for_threading (first, edge_count, t);
     584         6059 :                   update_br_prob_note (first);
     585              :                 }
     586              :               else
     587              :                 {
     588      6682875 :                   first->count -= edge_count;
     589              :                   /* It is possible that as the result of
     590              :                      threading we've removed edge as it is
     591              :                      threaded to the fallthru edge.  Avoid
     592              :                      getting out of sync.  */
     593      6682875 :                   if (n < nthreaded_edges
     594            0 :                       && first == threaded_edges [n]->src)
     595            0 :                     n++;
     596      6682875 :                   t = single_succ_edge (first);
     597              :                 }
     598              : 
     599      6688934 :               first = t->dest;
     600              :             }
     601      6688934 :           while (first != target);
     602              : 
     603      6579511 :           changed = true;
     604      6579511 :           continue;
     605      6579511 :         }
     606    560069493 :       ei_next (&ei);
     607              :     }
     608              : 
     609    404209576 :   free (threaded_edges);
     610    404209576 :   return changed;
     611              : }
     612              : 
     613              : 
     614              : /* Blocks A and B are to be merged into a single block.  A has no incoming
     615              :    fallthru edge, so it can be moved before B without adding or modifying
     616              :    any jumps (aside from the jump from A to B).  */
     617              : 
     618              : static void
     619        21772 : merge_blocks_move_predecessor_nojumps (basic_block a, basic_block b)
     620              : {
     621        21772 :   rtx_insn *barrier;
     622              : 
     623              :   /* If we are partitioning hot/cold basic blocks, we don't want to
     624              :      mess up unconditional or indirect jumps that cross between hot
     625              :      and cold sections.
     626              : 
     627              :      Basic block partitioning may result in some jumps that appear to
     628              :      be optimizable (or blocks that appear to be mergeable), but which really
     629              :      must be left untouched (they are required to make it safely across
     630              :      partition boundaries).  See the comments at the top of
     631              :      bb-reorder.cc:partition_hot_cold_basic_blocks for complete details.  */
     632              : 
     633        21772 :   if (BB_PARTITION (a) != BB_PARTITION (b))
     634              :     return;
     635              : 
     636        21772 :   barrier = next_nonnote_insn (BB_END (a));
     637        21772 :   gcc_assert (BARRIER_P (barrier));
     638        21772 :   delete_insn (barrier);
     639              : 
     640              :   /* Scramble the insn chain.  */
     641        21772 :   if (BB_END (a) != PREV_INSN (BB_HEAD (b)))
     642        21743 :     reorder_insns_nobb (BB_HEAD (a), BB_END (a), PREV_INSN (BB_HEAD (b)));
     643        21772 :   df_set_bb_dirty (a);
     644              : 
     645        21772 :   if (dump_file)
     646            0 :     fprintf (dump_file, "Moved block %d before %d and merged.\n",
     647              :              a->index, b->index);
     648              : 
     649              :   /* Swap the records for the two blocks around.  */
     650              : 
     651        21772 :   unlink_block (a);
     652        21772 :   link_block (a, b->prev_bb);
     653              : 
     654              :   /* Now blocks A and B are contiguous.  Merge them.  */
     655        21772 :   merge_blocks (a, b);
     656              : }
     657              : 
     658              : /* Blocks A and B are to be merged into a single block.  B has no outgoing
     659              :    fallthru edge, so it can be moved after A without adding or modifying
     660              :    any jumps (aside from the jump from A to B).  */
     661              : 
     662              : static void
     663        31280 : merge_blocks_move_successor_nojumps (basic_block a, basic_block b)
     664              : {
     665        31280 :   rtx_insn *barrier, *real_b_end;
     666        31280 :   rtx_insn *label;
     667        31280 :   rtx_jump_table_data *table;
     668              : 
     669              :   /* If we are partitioning hot/cold basic blocks, we don't want to
     670              :      mess up unconditional or indirect jumps that cross between hot
     671              :      and cold sections.
     672              : 
     673              :      Basic block partitioning may result in some jumps that appear to
     674              :      be optimizable (or blocks that appear to be mergeable), but which really
     675              :      must be left untouched (they are required to make it safely across
     676              :      partition boundaries).  See the comments at the top of
     677              :      bb-reorder.cc:partition_hot_cold_basic_blocks for complete details.  */
     678              : 
     679        31280 :   if (BB_PARTITION (a) != BB_PARTITION (b))
     680            0 :     return;
     681              : 
     682        31280 :   real_b_end = BB_END (b);
     683              : 
     684              :   /* If there is a jump table following block B temporarily add the jump table
     685              :      to block B so that it will also be moved to the correct location.  */
     686        31280 :   if (tablejump_p (BB_END (b), &label, &table)
     687        31280 :       && prev_active_insn (label) == BB_END (b))
     688              :     {
     689            0 :       BB_END (b) = table;
     690              :     }
     691              : 
     692              :   /* There had better have been a barrier there.  Delete it.  */
     693        31280 :   barrier = NEXT_INSN (BB_END (b));
     694        31280 :   if (barrier && BARRIER_P (barrier))
     695        31280 :     delete_insn (barrier);
     696              : 
     697              : 
     698              :   /* Scramble the insn chain.  */
     699        31280 :   reorder_insns_nobb (BB_HEAD (b), BB_END (b), BB_END (a));
     700              : 
     701              :   /* Restore the real end of b.  */
     702        31280 :   BB_END (b) = real_b_end;
     703              : 
     704        31280 :   if (dump_file)
     705           20 :     fprintf (dump_file, "Moved block %d after %d and merged.\n",
     706              :              b->index, a->index);
     707              : 
     708              :   /* Now blocks A and B are contiguous.  Merge them.  */
     709        31280 :   merge_blocks (a, b);
     710              : }
     711              : 
     712              : /* Attempt to merge basic blocks that are potentially non-adjacent.
     713              :    Return NULL iff the attempt failed, otherwise return basic block
     714              :    where cleanup_cfg should continue.  Because the merging commonly
     715              :    moves basic block away or introduces another optimization
     716              :    possibility, return basic block just before B so cleanup_cfg don't
     717              :    need to iterate.
     718              : 
     719              :    It may be good idea to return basic block before C in the case
     720              :    C has been moved after B and originally appeared earlier in the
     721              :    insn sequence, but we have no information available about the
     722              :    relative ordering of these two.  Hopefully it is not too common.  */
     723              : 
     724              : static basic_block
     725      7022866 : merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
     726              : {
     727      7022866 :   basic_block next;
     728              : 
     729              :   /* If we are partitioning hot/cold basic blocks, we don't want to
     730              :      mess up unconditional or indirect jumps that cross between hot
     731              :      and cold sections.
     732              : 
     733              :      Basic block partitioning may result in some jumps that appear to
     734              :      be optimizable (or blocks that appear to be mergeable), but which really
     735              :      must be left untouched (they are required to make it safely across
     736              :      partition boundaries).  See the comments at the top of
     737              :      bb-reorder.cc:partition_hot_cold_basic_blocks for complete details.  */
     738              : 
     739      7022866 :   if (BB_PARTITION (b) != BB_PARTITION (c))
     740              :     return NULL;
     741              : 
     742              :   /* If B has a fallthru edge to C, no need to move anything.  */
     743      6632105 :   if (e->flags & EDGE_FALLTHRU)
     744              :     {
     745      3802939 :       int b_index = b->index, c_index = c->index;
     746              : 
     747              :       /* Protect the loop latches.  */
     748      3802939 :       if (current_loops && c->loop_father->latch == c)
     749              :         return NULL;
     750              : 
     751      3758118 :       merge_blocks (b, c);
     752      3758118 :       update_forwarder_flag (b);
     753              : 
     754      3758118 :       if (dump_file)
     755          836 :         fprintf (dump_file, "Merged %d and %d without moving.\n",
     756              :                  b_index, c_index);
     757              : 
     758      4867639 :       return b->prev_bb == ENTRY_BLOCK_PTR_FOR_FN (cfun) ? b : b->prev_bb;
     759              :     }
     760              : 
     761              :   /* Otherwise we will need to move code around.  Do that only if expensive
     762              :      transformations are allowed.  */
     763      2829166 :   else if (mode & CLEANUP_EXPENSIVE)
     764              :     {
     765       937597 :       edge tmp_edge, b_fallthru_edge;
     766       937597 :       bool c_has_outgoing_fallthru;
     767       937597 :       bool b_has_incoming_fallthru;
     768              : 
     769              :       /* Avoid overactive code motion, as the forwarder blocks should be
     770              :          eliminated by edge redirection instead.  One exception might have
     771              :          been if B is a forwarder block and C has no fallthru edge, but
     772              :          that should be cleaned up by bb-reorder instead.  */
     773       937597 :       if (FORWARDER_BLOCK_P (b) || FORWARDER_BLOCK_P (c))
     774              :         return NULL;
     775              : 
     776              :       /* We must make sure to not munge nesting of lexical blocks,
     777              :          and loop notes.  This is done by squeezing out all the notes
     778              :          and leaving them there to lie.  Not ideal, but functional.  */
     779              : 
     780        55232 :       tmp_edge = find_fallthru_edge (c->succs);
     781        55232 :       c_has_outgoing_fallthru = (tmp_edge != NULL);
     782              : 
     783        55232 :       tmp_edge = find_fallthru_edge (b->preds);
     784        55232 :       b_has_incoming_fallthru = (tmp_edge != NULL);
     785        55232 :       b_fallthru_edge = tmp_edge;
     786        55232 :       next = b->prev_bb;
     787        55232 :       if (next == c)
     788           57 :         next = next->prev_bb;
     789              : 
     790              :       /* Otherwise, we're going to try to move C after B.  If C does
     791              :          not have an outgoing fallthru, then it can be moved
     792              :          immediately after B without introducing or modifying jumps.  */
     793        55232 :       if (! c_has_outgoing_fallthru)
     794              :         {
     795        31280 :           merge_blocks_move_successor_nojumps (b, c);
     796        31280 :           return next == ENTRY_BLOCK_PTR_FOR_FN (cfun) ? next->next_bb : next;
     797              :         }
     798              : 
     799              :       /* If B does not have an incoming fallthru, then it can be moved
     800              :          immediately before C without introducing or modifying jumps.
     801              :          C cannot be the first block, so we do not have to worry about
     802              :          accessing a non-existent block.  */
     803              : 
     804        23952 :       if (b_has_incoming_fallthru)
     805              :         {
     806        21756 :           basic_block bb;
     807              : 
     808        21756 :           if (b_fallthru_edge->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
     809              :             return NULL;
     810        19576 :           bb = force_nonfallthru (b_fallthru_edge);
     811        19576 :           if (bb)
     812        14930 :             notice_new_block (bb);
     813              :         }
     814              : 
     815        21772 :       merge_blocks_move_predecessor_nojumps (b, c);
     816        21772 :       return next == ENTRY_BLOCK_PTR_FOR_FN (cfun) ? next->next_bb : next;
     817              :     }
     818              : 
     819              :   return NULL;
     820              : }
     821              : 
     822              : 
     823              : /* Removes the memory attributes of MEM expression
     824              :    if they are not equal.  */
     825              : 
     826              : static void
     827    148255710 : merge_memattrs (rtx x, rtx y)
     828              : {
     829    148255710 :   int i;
     830    148255710 :   int j;
     831    148255710 :   enum rtx_code code;
     832    148255710 :   const char *fmt;
     833              : 
     834    148255710 :   if (x == y)
     835              :     return;
     836    110635328 :   if (x == 0 || y == 0)
     837              :     return;
     838              : 
     839    110597079 :   code = GET_CODE (x);
     840              : 
     841    110597079 :   if (code != GET_CODE (y))
     842              :     return;
     843              : 
     844    110597067 :   if (GET_MODE (x) != GET_MODE (y))
     845              :     return;
     846              : 
     847    110593891 :   if (code == MEM && !mem_attrs_eq_p (MEM_ATTRS (x), MEM_ATTRS (y)))
     848              :     {
     849        46599 :       if (! MEM_ATTRS (x))
     850          769 :         MEM_ATTRS (y) = 0;
     851        45830 :       else if (! MEM_ATTRS (y))
     852         1322 :         MEM_ATTRS (x) = 0;
     853              :       else
     854              :         {
     855        44508 :           if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y))
     856              :             {
     857         2970 :               set_mem_alias_set (x, 0);
     858         2970 :               set_mem_alias_set (y, 0);
     859              :             }
     860              : 
     861        44508 :           if (! mem_expr_equal_p (MEM_EXPR (x), MEM_EXPR (y)))
     862              :             {
     863        43678 :               set_mem_expr (x, 0);
     864        43678 :               set_mem_expr (y, 0);
     865        43678 :               clear_mem_offset (x);
     866        43678 :               clear_mem_offset (y);
     867              :             }
     868          830 :           else if (MEM_OFFSET_KNOWN_P (x) != MEM_OFFSET_KNOWN_P (y)
     869          830 :                    || (MEM_OFFSET_KNOWN_P (x)
     870            0 :                        && maybe_ne (MEM_OFFSET (x), MEM_OFFSET (y))))
     871              :             {
     872            0 :               clear_mem_offset (x);
     873            0 :               clear_mem_offset (y);
     874              :             }
     875              : 
     876        51233 :           if (!MEM_SIZE_KNOWN_P (x))
     877          214 :             clear_mem_size (y);
     878        50832 :           else if (!MEM_SIZE_KNOWN_P (y))
     879            0 :             clear_mem_size (x);
     880        44294 :           else if (known_le (MEM_SIZE (x), MEM_SIZE (y)))
     881        44250 :             set_mem_size (x, MEM_SIZE (y));
     882           44 :           else if (known_le (MEM_SIZE (y), MEM_SIZE (x)))
     883           44 :             set_mem_size (y, MEM_SIZE (x));
     884              :           else
     885              :             {
     886              :               /* The sizes aren't ordered, so we can't merge them.  */
     887              :               clear_mem_size (x);
     888              :               clear_mem_size (y);
     889              :             }
     890              : 
     891        57984 :           set_mem_align (x, MIN (MEM_ALIGN (x), MEM_ALIGN (y)));
     892        51267 :           set_mem_align (y, MEM_ALIGN (x));
     893              :         }
     894              :     }
     895    110593891 :   if (code == MEM)
     896              :     {
     897      6095882 :       if (MEM_READONLY_P (x) != MEM_READONLY_P (y))
     898              :         {
     899            0 :           MEM_READONLY_P (x) = 0;
     900            0 :           MEM_READONLY_P (y) = 0;
     901              :         }
     902      6095882 :       if (MEM_NOTRAP_P (x) != MEM_NOTRAP_P (y))
     903              :         {
     904          191 :           MEM_NOTRAP_P (x) = 0;
     905          191 :           MEM_NOTRAP_P (y) = 0;
     906              :         }
     907      6095882 :       if (MEM_VOLATILE_P (x) != MEM_VOLATILE_P (y))
     908              :         {
     909          150 :           MEM_VOLATILE_P (x) = 1;
     910          150 :           MEM_VOLATILE_P (y) = 1;
     911              :         }
     912              :     }
     913              : 
     914    110593891 :   fmt = GET_RTX_FORMAT (code);
     915    336078785 :   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     916              :     {
     917    225484894 :       switch (fmt[i])
     918              :         {
     919       384692 :         case 'E':
     920              :           /* Two vectors must have the same length.  */
     921       384692 :           if (XVECLEN (x, i) != XVECLEN (y, i))
     922              :             return;
     923              : 
     924      1137264 :           for (j = 0; j < XVECLEN (x, i); j++)
     925       752572 :             merge_memattrs (XVECEXP (x, i, j), XVECEXP (y, i, j));
     926              : 
     927              :           break;
     928              : 
     929    138760928 :         case 'e':
     930    138760928 :           merge_memattrs (XEXP (x, i), XEXP (y, i));
     931              :         }
     932              :     }
     933              :   return;
     934              : }
     935              : 
     936              : 
     937              :  /* Checks if patterns P1 and P2 are equivalent, apart from the possibly
     938              :     different single sets S1 and S2.  */
     939              : 
     940              : static bool
     941            2 : equal_different_set_p (rtx p1, rtx s1, rtx p2, rtx s2)
     942              : {
     943            2 :   int i;
     944            2 :   rtx e1, e2;
     945              : 
     946            2 :   if (p1 == s1 && p2 == s2)
     947              :     return true;
     948              : 
     949            0 :   if (GET_CODE (p1) != PARALLEL || GET_CODE (p2) != PARALLEL)
     950              :     return false;
     951              : 
     952            0 :   if (XVECLEN (p1, 0) != XVECLEN (p2, 0))
     953              :     return false;
     954              : 
     955            0 :   for (i = 0; i < XVECLEN (p1, 0); i++)
     956              :     {
     957            0 :       e1 = XVECEXP (p1, 0, i);
     958            0 :       e2 = XVECEXP (p2, 0, i);
     959            0 :       if (e1 == s1 && e2 == s2)
     960            0 :         continue;
     961            0 :       if (reload_completed
     962            0 :           ? rtx_renumbered_equal_p (e1, e2) : rtx_equal_p (e1, e2))
     963            0 :         continue;
     964              : 
     965              :       return false;
     966              :     }
     967              : 
     968              :   return true;
     969              : }
     970              : 
     971              : 
     972              : /* NOTE1 is the REG_EQUAL note, if any, attached to an insn
     973              :    that is a single_set with a SET_SRC of SRC1.  Similarly
     974              :    for NOTE2/SRC2.
     975              : 
     976              :    So effectively NOTE1/NOTE2 are an alternate form of
     977              :    SRC1/SRC2 respectively.
     978              : 
     979              :    Return nonzero if SRC1 or NOTE1 has the same constant
     980              :    integer value as SRC2 or NOTE2.   Else return zero.  */
     981              : static int
     982      7735547 : values_equal_p (rtx note1, rtx note2, rtx src1, rtx src2)
     983              : {
     984      7735547 :   if (note1
     985      7735547 :       && note2
     986      1283002 :       && CONST_INT_P (XEXP (note1, 0))
     987      7792126 :       && rtx_equal_p (XEXP (note1, 0), XEXP (note2, 0)))
     988              :     return 1;
     989              : 
     990      7735547 :   if (!note1
     991      7735547 :       && !note2
     992      5983377 :       && CONST_INT_P (src1)
     993      2535204 :       && CONST_INT_P (src2)
     994     10168213 :       && rtx_equal_p (src1, src2))
     995              :     return 1;
     996              : 
     997      7735547 :   if (note1
     998      1557821 :       && CONST_INT_P (src2)
     999      7879995 :       && rtx_equal_p (XEXP (note1, 0), src2))
    1000              :     return 1;
    1001              : 
    1002      7735547 :   if (note2
    1003      1477351 :       && CONST_INT_P (src1)
    1004      7804269 :       && rtx_equal_p (XEXP (note2, 0), src1))
    1005              :     return 1;
    1006              : 
    1007              :   return 0;
    1008              : }
    1009              : 
    1010              : /* Examine register notes on I1 and I2 and return:
    1011              :    - dir_forward if I1 can be replaced by I2, or
    1012              :    - dir_backward if I2 can be replaced by I1, or
    1013              :    - dir_both if both are the case.  */
    1014              : 
    1015              : static enum replace_direction
    1016     13966723 : can_replace_by (rtx_insn *i1, rtx_insn *i2)
    1017              : {
    1018     13966723 :   rtx s1, s2, d1, d2, src1, src2, note1, note2;
    1019     13966723 :   bool c1, c2;
    1020              : 
    1021              :   /* Check for 2 sets.  */
    1022     13966723 :   s1 = single_set (i1);
    1023     13966723 :   s2 = single_set (i2);
    1024     13966723 :   if (s1 == NULL_RTX || s2 == NULL_RTX)
    1025              :     return dir_none;
    1026              : 
    1027              :   /* Check that the 2 sets set the same dest.  */
    1028     13192177 :   d1 = SET_DEST (s1);
    1029     13192177 :   d2 = SET_DEST (s2);
    1030     26384354 :   if (!(reload_completed
    1031     13192177 :         ? rtx_renumbered_equal_p (d1, d2) : rtx_equal_p (d1, d2)))
    1032              :     return dir_none;
    1033              : 
    1034              :   /* Find identical req_equiv or reg_equal note, which implies that the 2 sets
    1035              :      set dest to the same value.  */
    1036      7735547 :   note1 = find_reg_equal_equiv_note (i1);
    1037      7735547 :   note2 = find_reg_equal_equiv_note (i2);
    1038              : 
    1039      7735547 :   src1 = SET_SRC (s1);
    1040      7735547 :   src2 = SET_SRC (s2);
    1041              : 
    1042      7735547 :   if (!values_equal_p (note1, note2, src1, src2))
    1043              :     return dir_none;
    1044              : 
    1045            2 :   if (!equal_different_set_p (PATTERN (i1), s1, PATTERN (i2), s2))
    1046              :     return dir_none;
    1047              : 
    1048              :   /* Although the 2 sets set dest to the same value, we cannot replace
    1049              :        (set (dest) (const_int))
    1050              :      by
    1051              :        (set (dest) (reg))
    1052              :      because we don't know if the reg is live and has the same value at the
    1053              :      location of replacement.  */
    1054            2 :   c1 = CONST_INT_P (src1);
    1055            2 :   c2 = CONST_INT_P (src2);
    1056            2 :   if (c1 && c2)
    1057              :     return dir_both;
    1058            2 :   else if (c2)
    1059              :     return dir_forward;
    1060            2 :   else if (c1)
    1061              :     return dir_backward;
    1062              : 
    1063              :   return dir_none;
    1064              : }
    1065              : 
    1066              : /* Merges directions A and B.  */
    1067              : 
    1068              : static enum replace_direction
    1069     23773927 : merge_dir (enum replace_direction a, enum replace_direction b)
    1070              : {
    1071              :   /* Implements the following table:
    1072              :         |bo fw bw no
    1073              :      ---+-----------
    1074              :      bo |bo fw bw no
    1075              :      fw |-- fw no no
    1076              :      bw |-- -- bw no
    1077              :      no |-- -- -- no.  */
    1078              : 
    1079            0 :   if (a == b)
    1080              :     return a;
    1081              : 
    1082     16336377 :   if (a == dir_both)
    1083              :     return b;
    1084      3845733 :   if (b == dir_both)
    1085            0 :     return a;
    1086              : 
    1087              :   return dir_none;
    1088              : }
    1089              : 
    1090              : /* Array of flags indexed by reg note kind, true if the given
    1091              :    reg note is CFA related.  */
    1092              : static const bool reg_note_cfa_p[] = {
    1093              : #undef REG_CFA_NOTE
    1094              : #define DEF_REG_NOTE(NAME) false,
    1095              : #define REG_CFA_NOTE(NAME) true,
    1096              : #include "reg-notes.def"
    1097              : #undef REG_CFA_NOTE
    1098              : #undef DEF_REG_NOTE
    1099              :   false
    1100              : };
    1101              : 
    1102              : /* Return true if I1 and I2 have identical CFA notes (the same order
    1103              :    and equivalent content).  */
    1104              : 
    1105              : static bool
    1106       639438 : insns_have_identical_cfa_notes (rtx_insn *i1, rtx_insn *i2)
    1107              : {
    1108       639438 :   rtx n1, n2;
    1109       639438 :   for (n1 = REG_NOTES (i1), n2 = REG_NOTES (i2); ;
    1110       501341 :        n1 = XEXP (n1, 1), n2 = XEXP (n2, 1))
    1111              :     {
    1112              :       /* Skip over reg notes not related to CFI information.  */
    1113      1667791 :       while (n1 && !reg_note_cfa_p[REG_NOTE_KIND (n1)])
    1114        25671 :         n1 = XEXP (n1, 1);
    1115      1165090 :       while (n2 && !reg_note_cfa_p[REG_NOTE_KIND (n2)])
    1116        24311 :         n2 = XEXP (n2, 1);
    1117      1140779 :       if (n1 == NULL_RTX && n2 == NULL_RTX)
    1118              :         return true;
    1119       622516 :       if (n1 == NULL_RTX || n2 == NULL_RTX)
    1120              :         return false;
    1121       617985 :       if (XEXP (n1, 0) == XEXP (n2, 0))
    1122              :         ;
    1123       617979 :       else if (XEXP (n1, 0) == NULL_RTX || XEXP (n2, 0) == NULL_RTX)
    1124              :         return false;
    1125      1235958 :       else if (!(reload_completed
    1126       617979 :                  ? rtx_renumbered_equal_p (XEXP (n1, 0), XEXP (n2, 0))
    1127            0 :                  : rtx_equal_p (XEXP (n1, 0), XEXP (n2, 0))))
    1128              :         return false;
    1129              :     }
    1130              : }
    1131              : 
    1132              : /* Examine I1 and I2 and return:
    1133              :    - dir_forward if I1 can be replaced by I2, or
    1134              :    - dir_backward if I2 can be replaced by I1, or
    1135              :    - dir_both if both are the case.  */
    1136              : 
    1137              : static enum replace_direction
    1138     40503134 : old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx_insn *i1, rtx_insn *i2)
    1139              : {
    1140     40503134 :   rtx p1, p2;
    1141              : 
    1142              :   /* Verify that I1 and I2 are equivalent.  */
    1143     40503134 :   if (GET_CODE (i1) != GET_CODE (i2))
    1144              :     return dir_none;
    1145              : 
    1146              :   /* __builtin_unreachable() may lead to empty blocks (ending with
    1147              :      NOTE_INSN_BASIC_BLOCK).  They may be crossjumped. */
    1148     34940366 :   if (NOTE_INSN_BASIC_BLOCK_P (i1) && NOTE_INSN_BASIC_BLOCK_P (i2))
    1149              :     return dir_both;
    1150              : 
    1151              :   /* ??? Do not allow cross-jumping between different stack levels.  */
    1152     34862711 :   p1 = find_reg_note (i1, REG_ARGS_SIZE, NULL);
    1153     34862711 :   p2 = find_reg_note (i2, REG_ARGS_SIZE, NULL);
    1154     34862711 :   if (p1 && p2)
    1155              :     {
    1156      3968596 :       p1 = XEXP (p1, 0);
    1157      3968596 :       p2 = XEXP (p2, 0);
    1158      3968596 :       if (!rtx_equal_p (p1, p2))
    1159              :         return dir_none;
    1160              : 
    1161              :       /* ??? Worse, this adjustment had better be constant lest we
    1162              :          have differing incoming stack levels.  */
    1163      3867697 :       if (!frame_pointer_needed
    1164      3867697 :           && known_eq (find_args_size_adjust (i1), HOST_WIDE_INT_MIN))
    1165           22 :         return dir_none;
    1166              :     }
    1167     30894115 :   else if (p1 || p2)
    1168              :     return dir_none;
    1169              : 
    1170              :   /* Do not allow cross-jumping between frame related insns and other
    1171              :      insns.  */
    1172     33212141 :   if (RTX_FRAME_RELATED_P (i1) != RTX_FRAME_RELATED_P (i2))
    1173              :     return dir_none;
    1174              : 
    1175     32612805 :   p1 = PATTERN (i1);
    1176     32612805 :   p2 = PATTERN (i2);
    1177              : 
    1178     32612805 :   if (GET_CODE (p1) != GET_CODE (p2))
    1179              :     return dir_none;
    1180              : 
    1181              :   /* If this is a CALL_INSN, compare register usage information.
    1182              :      If we don't check this on stack register machines, the two
    1183              :      CALL_INSNs might be merged leaving reg-stack.cc with mismatching
    1184              :      numbers of stack registers in the same basic block.
    1185              :      If we don't check this on machines with delay slots, a delay slot may
    1186              :      be filled that clobbers a parameter expected by the subroutine.
    1187              : 
    1188              :      ??? We take the simple route for now and assume that if they're
    1189              :      equal, they were constructed identically.
    1190              : 
    1191              :      Also check for identical exception regions.  */
    1192              : 
    1193     30203360 :   if (CALL_P (i1))
    1194              :     {
    1195              :       /* Ensure the same EH region.  */
    1196     11975957 :       rtx n1 = find_reg_note (i1, REG_EH_REGION, 0);
    1197     11975957 :       rtx n2 = find_reg_note (i2, REG_EH_REGION, 0);
    1198              : 
    1199     11975957 :       if (!n1 && n2)
    1200              :         return dir_none;
    1201              : 
    1202     11879948 :       if (n1 && (!n2 || XEXP (n1, 0) != XEXP (n2, 0)))
    1203              :         return dir_none;
    1204              : 
    1205     10952922 :       if (!rtx_equal_p (CALL_INSN_FUNCTION_USAGE (i1),
    1206     10952922 :                         CALL_INSN_FUNCTION_USAGE (i2))
    1207      7324927 :           || CALL_INSN_ABI_ID (i1) != CALL_INSN_ABI_ID (i2)
    1208     18277849 :           || SIBLING_CALL_P (i1) != SIBLING_CALL_P (i2))
    1209              :         return dir_none;
    1210              : 
    1211              :       /* For address sanitizer, never crossjump __asan_report_* builtins,
    1212              :          otherwise errors might be reported on incorrect lines.  */
    1213      7324927 :       if (flag_sanitize & SANITIZE_ADDRESS)
    1214              :         {
    1215       366909 :           rtx call = get_call_rtx_from (i1);
    1216       366909 :           if (call && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
    1217              :             {
    1218       366909 :               rtx symbol = XEXP (XEXP (call, 0), 0);
    1219       366909 :               if (SYMBOL_REF_DECL (symbol)
    1220       366909 :                   && TREE_CODE (SYMBOL_REF_DECL (symbol)) == FUNCTION_DECL)
    1221              :                 {
    1222       366909 :                   if ((DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (symbol))
    1223       366909 :                        == BUILT_IN_NORMAL)
    1224       364904 :                       && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol))
    1225              :                          >= BUILT_IN_ASAN_REPORT_LOAD1
    1226       730311 :                       && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol))
    1227              :                          <= BUILT_IN_ASAN_STOREN)
    1228              :                     return dir_none;
    1229              :                 }
    1230              :             }
    1231              :         }
    1232              : 
    1233      6962475 :       if (insn_callee_abi (i1) != insn_callee_abi (i2))
    1234              :         return dir_none;
    1235              :     }
    1236              : 
    1237              :   /* If both i1 and i2 are frame related, verify all the CFA notes
    1238              :      in the same order and with the same content.  */
    1239     25130886 :   if (RTX_FRAME_RELATED_P (i1) && !insns_have_identical_cfa_notes (i1, i2))
    1240              :     return dir_none;
    1241              : 
    1242              : #ifdef STACK_REGS
    1243              :   /* If cross_jump_death_matters is not 0, the insn's mode
    1244              :      indicates whether or not the insn contains any stack-like
    1245              :      regs.  */
    1246              : 
    1247     25009711 :   if ((mode & CLEANUP_POST_REGSTACK) && stack_regs_mentioned (i1))
    1248              :     {
    1249              :       /* If register stack conversion has already been done, then
    1250              :          death notes must also be compared before it is certain that
    1251              :          the two instruction streams match.  */
    1252              : 
    1253              :       rtx note;
    1254              :       HARD_REG_SET i1_regset, i2_regset;
    1255              : 
    1256            0 :       CLEAR_HARD_REG_SET (i1_regset);
    1257            0 :       CLEAR_HARD_REG_SET (i2_regset);
    1258              : 
    1259            0 :       for (note = REG_NOTES (i1); note; note = XEXP (note, 1))
    1260            0 :         if (REG_NOTE_KIND (note) == REG_DEAD && STACK_REG_P (XEXP (note, 0)))
    1261            0 :           SET_HARD_REG_BIT (i1_regset, REGNO (XEXP (note, 0)));
    1262              : 
    1263            0 :       for (note = REG_NOTES (i2); note; note = XEXP (note, 1))
    1264            0 :         if (REG_NOTE_KIND (note) == REG_DEAD && STACK_REG_P (XEXP (note, 0)))
    1265            0 :           SET_HARD_REG_BIT (i2_regset, REGNO (XEXP (note, 0)));
    1266              : 
    1267            0 :       if (i1_regset != i2_regset)
    1268            0 :         return dir_none;
    1269              :     }
    1270              : #endif
    1271              : 
    1272     25009711 :   if (reload_completed
    1273     25009711 :       ? rtx_renumbered_equal_p (p1, p2) : rtx_equal_p (p1, p2))
    1274              :     return dir_both;
    1275              : 
    1276     13966723 :   return can_replace_by (i1, i2);
    1277              : }
    1278              : 
    1279              : /* When comparing insns I1 and I2 in flow_find_cross_jump or
    1280              :    flow_find_head_matching_sequence, ensure the notes match.  */
    1281              : 
    1282              : static void
    1283      8742210 : merge_notes (rtx_insn *i1, rtx_insn *i2)
    1284              : {
    1285              :   /* If the merged insns have different REG_EQUAL notes, then
    1286              :      remove them.  */
    1287      8742210 :   rtx equiv1 = find_reg_equal_equiv_note (i1);
    1288      8742210 :   rtx equiv2 = find_reg_equal_equiv_note (i2);
    1289              : 
    1290      8742210 :   if (equiv1 && !equiv2)
    1291        23010 :     remove_note (i1, equiv1);
    1292      8719200 :   else if (!equiv1 && equiv2)
    1293         6971 :     remove_note (i2, equiv2);
    1294      8712229 :   else if (equiv1 && equiv2
    1295      8712229 :            && !rtx_equal_p (XEXP (equiv1, 0), XEXP (equiv2, 0)))
    1296              :     {
    1297          324 :       remove_note (i1, equiv1);
    1298          324 :       remove_note (i2, equiv2);
    1299              :     }
    1300      8742210 : }
    1301              : 
    1302              :  /* Walks from I1 in BB1 backward till the next non-debug insn, and returns the
    1303              :     resulting insn in I1, and the corresponding bb in BB1.  At the head of a
    1304              :     bb, if there is a predecessor bb that reaches this bb via fallthru, and
    1305              :     FOLLOW_FALLTHRU, walks further in the predecessor bb and registers this in
    1306              :     DID_FALLTHRU.  Otherwise, stops at the head of the bb.  */
    1307              : 
    1308              : static void
    1309     49110144 : walk_to_nondebug_insn (rtx_insn **i1, basic_block *bb1, bool follow_fallthru,
    1310              :                        bool *did_fallthru)
    1311              : {
    1312     49110144 :   edge fallthru;
    1313              : 
    1314     49110144 :   *did_fallthru = false;
    1315              : 
    1316              :   /* Ignore notes.  */
    1317     67352399 :   while (!NONDEBUG_INSN_P (*i1))
    1318              :     {
    1319     19406873 :       if (*i1 != BB_HEAD (*bb1))
    1320              :         {
    1321     18040635 :           *i1 = PREV_INSN (*i1);
    1322     18040635 :           continue;
    1323              :         }
    1324              : 
    1325      1366238 :       if (!follow_fallthru)
    1326              :         return;
    1327              : 
    1328      1192233 :       fallthru = find_fallthru_edge ((*bb1)->preds);
    1329       476683 :       if (!fallthru || fallthru->src == ENTRY_BLOCK_PTR_FOR_FN (cfun)
    1330      1668859 :           || !single_succ_p (fallthru->src))
    1331              :         return;
    1332              : 
    1333       201620 :       *bb1 = fallthru->src;
    1334       201620 :       *i1 = BB_END (*bb1);
    1335       201620 :       *did_fallthru = true;
    1336              :      }
    1337              : }
    1338              : 
    1339              : /* Look through the insns at the end of BB1 and BB2 and find the longest
    1340              :    sequence that are either equivalent, or allow forward or backward
    1341              :    replacement.  Store the first insns for that sequence in *F1 and *F2 and
    1342              :    return the sequence length.
    1343              : 
    1344              :    DIR_P indicates the allowed replacement direction on function entry, and
    1345              :    the actual replacement direction on function exit.  If NULL, only equivalent
    1346              :    sequences are allowed.
    1347              : 
    1348              :    To simplify callers of this function, if the blocks match exactly,
    1349              :    store the head of the blocks in *F1 and *F2.  */
    1350              : 
    1351              : int
    1352     16024789 : flow_find_cross_jump (basic_block bb1, basic_block bb2, rtx_insn **f1,
    1353              :                       rtx_insn **f2, enum replace_direction *dir_p)
    1354              : {
    1355     16024789 :   rtx_insn *i1, *i2, *last1, *last2, *afterlast1, *afterlast2;
    1356     16024789 :   int ninsns = 0;
    1357     16024789 :   enum replace_direction dir, last_dir, afterlast_dir;
    1358     16024789 :   bool follow_fallthru, did_fallthru;
    1359              : 
    1360     16024789 :   if (dir_p)
    1361     16024789 :     dir = *dir_p;
    1362              :   else
    1363              :     dir = dir_both;
    1364     16024789 :   afterlast_dir = dir;
    1365     16024789 :   last_dir = afterlast_dir;
    1366              : 
    1367              :   /* Skip simple jumps at the end of the blocks.  Complex jumps still
    1368              :      need to be compared for equivalence, which we'll do below.  */
    1369              : 
    1370     16024789 :   i1 = BB_END (bb1);
    1371     16024789 :   last1 = afterlast1 = last2 = afterlast2 = NULL;
    1372     16024789 :   if (onlyjump_p (i1)
    1373     16024789 :       || (returnjump_p (i1) && !side_effects_p (PATTERN (i1))))
    1374              :     {
    1375     14397166 :       last1 = i1;
    1376     14397166 :       i1 = PREV_INSN (i1);
    1377              :     }
    1378              : 
    1379     16024789 :   i2 = BB_END (bb2);
    1380     16024789 :   if (onlyjump_p (i2)
    1381     16024789 :       || (returnjump_p (i2) && !side_effects_p (PATTERN (i2))))
    1382              :     {
    1383     11697284 :       last2 = i2;
    1384              :       /* Count everything except for unconditional jump as insn.
    1385              :          Don't count any jumps if dir_p is NULL.  */
    1386     11697284 :       if (!simplejump_p (i2) && !returnjump_p (i2) && last1 && dir_p)
    1387              :         ninsns++;
    1388     11697284 :       i2 = PREV_INSN (i2);
    1389              :     }
    1390              : 
    1391     33085355 :   while (true)
    1392              :     {
    1393              :       /* In the following example, we can replace all jumps to C by jumps to A.
    1394              : 
    1395              :          This removes 4 duplicate insns.
    1396              :          [bb A] insn1            [bb C] insn1
    1397              :                 insn2                   insn2
    1398              :          [bb B] insn3                   insn3
    1399              :                 insn4                   insn4
    1400              :                 jump_insn               jump_insn
    1401              : 
    1402              :          We could also replace all jumps to A by jumps to C, but that leaves B
    1403              :          alive, and removes only 2 duplicate insns.  In a subsequent crossjump
    1404              :          step, all jumps to B would be replaced with jumps to the middle of C,
    1405              :          achieving the same result with more effort.
    1406              :          So we allow only the first possibility, which means that we don't allow
    1407              :          fallthru in the block that's being replaced.  */
    1408              : 
    1409     24555072 :       follow_fallthru = dir_p && dir != dir_forward;
    1410     24555072 :       walk_to_nondebug_insn (&i1, &bb1, follow_fallthru, &did_fallthru);
    1411     24555072 :       if (did_fallthru)
    1412        28537 :         dir = dir_backward;
    1413              : 
    1414     24555072 :       follow_fallthru = dir_p && dir != dir_backward;
    1415     24555072 :       walk_to_nondebug_insn (&i2, &bb2, follow_fallthru, &did_fallthru);
    1416     24555072 :       if (did_fallthru)
    1417       173073 :         dir = dir_forward;
    1418              : 
    1419     24555072 :       if (i1 == BB_HEAD (bb1) || i2 == BB_HEAD (bb2))
    1420              :         break;
    1421              : 
    1422              :       /* Do not turn corssing edge to non-crossing or vice versa after
    1423              :          reload. */
    1424     23773927 :       if (BB_PARTITION (BLOCK_FOR_INSN (i1))
    1425     23773927 :           != BB_PARTITION (BLOCK_FOR_INSN (i2))
    1426     23773927 :           && reload_completed)
    1427              :         break;
    1428              : 
    1429     23773927 :       dir = merge_dir (dir, old_insns_match_p (0, i1, i2));
    1430     21020927 :       if (dir == dir_none || (!dir_p && dir != dir_both))
    1431              :         break;
    1432              : 
    1433      8530283 :       merge_memattrs (i1, i2);
    1434              : 
    1435              :       /* Don't begin a cross-jump with a NOTE insn.  */
    1436      8530283 :       if (INSN_P (i1))
    1437              :         {
    1438      8530283 :           merge_notes (i1, i2);
    1439              : 
    1440      8530283 :           afterlast1 = last1, afterlast2 = last2;
    1441      8530283 :           last1 = i1, last2 = i2;
    1442      8530283 :           afterlast_dir = last_dir;
    1443      8530283 :           last_dir = dir;
    1444      8530283 :           if (active_insn_p (i1))
    1445      8420080 :             ninsns++;
    1446              :         }
    1447              : 
    1448      8530283 :       i1 = PREV_INSN (i1);
    1449      8530283 :       i2 = PREV_INSN (i2);
    1450              :     }
    1451              : 
    1452              :   /* Include preceding notes and labels in the cross-jump.  One,
    1453              :      this may bring us to the head of the blocks as requested above.
    1454              :      Two, it keeps line number notes as matched as may be.  */
    1455     16024789 :   if (ninsns)
    1456              :     {
    1457      5113936 :       bb1 = BLOCK_FOR_INSN (last1);
    1458     12989915 :       while (last1 != BB_HEAD (bb1) && !NONDEBUG_INSN_P (PREV_INSN (last1)))
    1459              :         last1 = PREV_INSN (last1);
    1460              : 
    1461      9948559 :       if (last1 != BB_HEAD (bb1) && LABEL_P (PREV_INSN (last1)))
    1462              :         last1 = PREV_INSN (last1);
    1463              : 
    1464      5113936 :       bb2 = BLOCK_FOR_INSN (last2);
    1465     13080988 :       while (last2 != BB_HEAD (bb2) && !NONDEBUG_INSN_P (PREV_INSN (last2)))
    1466              :         last2 = PREV_INSN (last2);
    1467              : 
    1468      9638927 :       if (last2 != BB_HEAD (bb2) && LABEL_P (PREV_INSN (last2)))
    1469              :         last2 = PREV_INSN (last2);
    1470              : 
    1471      5113936 :       *f1 = last1;
    1472      5113936 :       *f2 = last2;
    1473              :     }
    1474              : 
    1475     16024789 :   if (dir_p)
    1476     16024789 :     *dir_p = last_dir;
    1477     16024789 :   return ninsns;
    1478              : }
    1479              : 
    1480              : /* Like flow_find_cross_jump, except start looking for a matching sequence from
    1481              :    the head of the two blocks.  Do not include jumps at the end.
    1482              :    If STOP_AFTER is nonzero, stop after finding that many matching
    1483              :    instructions.  If STOP_AFTER is zero, count all INSN_P insns, if it is
    1484              :    non-zero, only count active insns.  */
    1485              : 
    1486              : int
    1487      4665431 : flow_find_head_matching_sequence (basic_block bb1, basic_block bb2, rtx_insn **f1,
    1488              :                                   rtx_insn **f2, int stop_after)
    1489              : {
    1490      4665431 :   rtx_insn *i1, *i2, *last1, *last2, *beforelast1, *beforelast2;
    1491      4665431 :   int ninsns = 0;
    1492      4665431 :   edge e;
    1493      4665431 :   edge_iterator ei;
    1494      4665431 :   int nehedges1 = 0, nehedges2 = 0;
    1495              : 
    1496     11139060 :   FOR_EACH_EDGE (e, ei, bb1->succs)
    1497      6473629 :     if (e->flags & EDGE_EH)
    1498       363261 :       nehedges1++;
    1499     11569521 :   FOR_EACH_EDGE (e, ei, bb2->succs)
    1500      6904090 :     if (e->flags & EDGE_EH)
    1501       394745 :       nehedges2++;
    1502              : 
    1503      4665431 :   i1 = BB_HEAD (bb1);
    1504      4665431 :   i2 = BB_HEAD (bb2);
    1505      4665431 :   last1 = beforelast1 = last2 = beforelast2 = NULL;
    1506              : 
    1507       198906 :   while (true)
    1508              :     {
    1509              :       /* Ignore notes, except NOTE_INSN_EPILOGUE_BEG.  */
    1510     22201471 :       while (!NONDEBUG_INSN_P (i1) && i1 != BB_END (bb1))
    1511              :         {
    1512     17156870 :           if (NOTE_P (i1) && NOTE_KIND (i1) == NOTE_INSN_EPILOGUE_BEG)
    1513              :             break;
    1514     17138228 :           i1 = NEXT_INSN (i1);
    1515              :         }
    1516              : 
    1517     21955130 :       while (!NONDEBUG_INSN_P (i2) && i2 != BB_END (bb2))
    1518              :         {
    1519     17130248 :           if (NOTE_P (i2) && NOTE_KIND (i2) == NOTE_INSN_EPILOGUE_BEG)
    1520              :             break;
    1521     17090793 :           i2 = NEXT_INSN (i2);
    1522              :         }
    1523              : 
    1524      4864337 :       if ((i1 == BB_END (bb1) && !NONDEBUG_INSN_P (i1))
    1525      4851710 :           || (i2 == BB_END (bb2) && !NONDEBUG_INSN_P (i2)))
    1526              :         break;
    1527              : 
    1528      4847010 :       if (NOTE_P (i1) || NOTE_P (i2)
    1529      4790962 :           || JUMP_P (i1) || JUMP_P (i2))
    1530              :         break;
    1531              : 
    1532              :       /* A sanity check to make sure we're not merging insns with different
    1533              :          effects on EH.  If only one of them ends a basic block, it shouldn't
    1534              :          have an EH edge; if both end a basic block, there should be the same
    1535              :          number of EH edges.  */
    1536      3898916 :       if ((i1 == BB_END (bb1) && i2 != BB_END (bb2)
    1537       219823 :            && nehedges1 > 0)
    1538      3860043 :           || (i2 == BB_END (bb2) && i1 != BB_END (bb1)
    1539       238996 :               && nehedges2 > 0)
    1540      3832293 :           || (i1 == BB_END (bb1) && i2 == BB_END (bb2)
    1541        26744 :               && nehedges1 != nehedges2))
    1542              :         break;
    1543              : 
    1544      3828901 :       if (old_insns_match_p (0, i1, i2) != dir_both)
    1545              :         break;
    1546              : 
    1547       211927 :       merge_memattrs (i1, i2);
    1548              : 
    1549              :       /* Don't begin a cross-jump with a NOTE insn.  */
    1550       211927 :       if (INSN_P (i1))
    1551              :         {
    1552       211927 :           merge_notes (i1, i2);
    1553              : 
    1554       211927 :           beforelast1 = last1, beforelast2 = last2;
    1555       211927 :           last1 = i1, last2 = i2;
    1556       211927 :           if (!stop_after || active_insn_p (i1))
    1557       211927 :             ninsns++;
    1558              :         }
    1559              : 
    1560       211927 :       if (i1 == BB_END (bb1) || i2 == BB_END (bb2)
    1561       198906 :           || (stop_after > 0 && ninsns == stop_after))
    1562              :         break;
    1563              : 
    1564       198906 :       i1 = NEXT_INSN (i1);
    1565       198906 :       i2 = NEXT_INSN (i2);
    1566              :     }
    1567              : 
    1568      4665431 :   if (ninsns)
    1569              :     {
    1570       119181 :       *f1 = last1;
    1571       119181 :       *f2 = last2;
    1572              :     }
    1573              : 
    1574      4665431 :   return ninsns;
    1575              : }
    1576              : 
    1577              : /* Return true iff outgoing edges of BB1 and BB2 match, together with
    1578              :    the branch instruction.  This means that if we commonize the control
    1579              :    flow before end of the basic block, the semantic remains unchanged.
    1580              : 
    1581              :    We may assume that there exists one edge with a common destination.  */
    1582              : 
    1583              : static bool
    1584     47144490 : outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
    1585              : {
    1586     47144490 :   int nehedges1 = 0, nehedges2 = 0;
    1587     47144490 :   edge fallthru1 = 0, fallthru2 = 0;
    1588     47144490 :   edge e1, e2;
    1589     47144490 :   edge_iterator ei;
    1590              : 
    1591              :   /* If we performed shrink-wrapping, edges to the exit block can
    1592              :      only be distinguished for JUMP_INSNs.  The two paths may differ in
    1593              :      whether they went through the prologue.  Sibcalls are fine, we know
    1594              :      that we either didn't need or inserted an epilogue before them.  */
    1595     47144490 :   if (crtl->shrink_wrapped
    1596      1233610 :       && single_succ_p (bb1)
    1597       481987 :       && single_succ (bb1) == EXIT_BLOCK_PTR_FOR_FN (cfun)
    1598       155359 :       && (!JUMP_P (BB_END (bb1))
    1599              :           /* Punt if the only successor is a fake edge to exit, the jump
    1600              :              must be some weird one.  */
    1601        65657 :           || (single_succ_edge (bb1)->flags & EDGE_FAKE) != 0)
    1602     47234272 :       && !(CALL_P (BB_END (bb1)) && SIBLING_CALL_P (BB_END (bb1))))
    1603              :     return false;
    1604              : 
    1605              :   /* If BB1 has only one successor, we may be looking at either an
    1606              :      unconditional jump, or a fake edge to exit.  */
    1607     47090971 :   if (single_succ_p (bb1)
    1608     19010210 :       && (single_succ_edge (bb1)->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0
    1609     62558661 :       && (!JUMP_P (BB_END (bb1)) || simplejump_p (BB_END (bb1))))
    1610     15199415 :     return (single_succ_p (bb2)
    1611     14005484 :             && (single_succ_edge (bb2)->flags
    1612     14005484 :                 & (EDGE_COMPLEX | EDGE_FAKE)) == 0
    1613     29146425 :             && (!JUMP_P (BB_END (bb2)) || simplejump_p (BB_END (bb2))));
    1614              : 
    1615              :   /* Match conditional jumps - this may get tricky when fallthru and branch
    1616              :      edges are crossed.  */
    1617     31891556 :   if (EDGE_COUNT (bb1->succs) == 2
    1618     28002415 :       && any_condjump_p (BB_END (bb1))
    1619     50881546 :       && onlyjump_p (BB_END (bb1)))
    1620              :     {
    1621     18989990 :       edge b1, f1, b2, f2;
    1622     18989990 :       bool reverse, match;
    1623     18989990 :       rtx set1, set2, cond1, cond2;
    1624     18989990 :       enum rtx_code code1, code2;
    1625              : 
    1626     18989990 :       if (EDGE_COUNT (bb2->succs) != 2
    1627      8640839 :           || !any_condjump_p (BB_END (bb2))
    1628     27596098 :           || !onlyjump_p (BB_END (bb2)))
    1629     10383882 :         return false;
    1630              : 
    1631      8606108 :       b1 = BRANCH_EDGE (bb1);
    1632      8606108 :       b2 = BRANCH_EDGE (bb2);
    1633      8606108 :       f1 = FALLTHRU_EDGE (bb1);
    1634      8606108 :       f2 = FALLTHRU_EDGE (bb2);
    1635              : 
    1636              :       /* Get around possible forwarders on fallthru edges.  Other cases
    1637              :          should be optimized out already.  */
    1638      8606108 :       if (FORWARDER_BLOCK_P (f1->dest))
    1639      3317098 :         f1 = single_succ_edge (f1->dest);
    1640              : 
    1641      8606108 :       if (FORWARDER_BLOCK_P (f2->dest))
    1642      2514090 :         f2 = single_succ_edge (f2->dest);
    1643              : 
    1644              :       /* To simplify use of this function, return false if there are
    1645              :          unneeded forwarder blocks.  These will get eliminated later
    1646              :          during cleanup_cfg.  */
    1647      8606108 :       if (FORWARDER_BLOCK_P (f1->dest)
    1648      8600781 :           || FORWARDER_BLOCK_P (f2->dest)
    1649      8594961 :           || FORWARDER_BLOCK_P (b1->dest)
    1650      8570078 :           || FORWARDER_BLOCK_P (b2->dest))
    1651              :         return false;
    1652              : 
    1653      8544228 :       if (f1->dest == f2->dest && b1->dest == b2->dest)
    1654              :         reverse = false;
    1655      8346905 :       else if (f1->dest == b2->dest && b1->dest == f2->dest)
    1656              :         reverse = true;
    1657              :       else
    1658              :         return false;
    1659              : 
    1660       328974 :       set1 = pc_set (BB_END (bb1));
    1661       328974 :       set2 = pc_set (BB_END (bb2));
    1662       328974 :       if ((XEXP (SET_SRC (set1), 1) == pc_rtx)
    1663       328974 :           != (XEXP (SET_SRC (set2), 1) == pc_rtx))
    1664            0 :         reverse = !reverse;
    1665              : 
    1666       328974 :       cond1 = XEXP (SET_SRC (set1), 0);
    1667       328974 :       cond2 = XEXP (SET_SRC (set2), 0);
    1668       328974 :       code1 = GET_CODE (cond1);
    1669       328974 :       if (reverse)
    1670       131651 :         code2 = reversed_comparison_code (cond2, BB_END (bb2));
    1671              :       else
    1672       197323 :         code2 = GET_CODE (cond2);
    1673              : 
    1674       328974 :       if (code2 == UNKNOWN)
    1675              :         return false;
    1676              : 
    1677              :       /* Verify codes and operands match.  */
    1678       935630 :       match = ((code1 == code2
    1679       284718 :                 && rtx_renumbered_equal_p (XEXP (cond1, 0), XEXP (cond2, 0))
    1680       282485 :                 && rtx_renumbered_equal_p (XEXP (cond1, 1), XEXP (cond2, 1)))
    1681       331207 :                || (code1 == swap_condition (code2)
    1682         3630 :                    && rtx_renumbered_equal_p (XEXP (cond1, 1),
    1683         3630 :                                               XEXP (cond2, 0))
    1684            0 :                    && rtx_renumbered_equal_p (XEXP (cond1, 0),
    1685            0 :                                               XEXP (cond2, 1))));
    1686              : 
    1687              :       /* If we return true, we will join the blocks.  Which means that
    1688              :          we will only have one branch prediction bit to work with.  Thus
    1689              :          we require the existing branches to have probabilities that are
    1690              :          roughly similar.  */
    1691       282485 :       if (match
    1692       282485 :           && optimize_bb_for_speed_p (bb1)
    1693       255324 :           && optimize_bb_for_speed_p (bb2))
    1694              :         {
    1695       245916 :           profile_probability prob2;
    1696              : 
    1697       245916 :           if (b1->dest == b2->dest)
    1698       149416 :             prob2 = b2->probability;
    1699              :           else
    1700              :             /* Do not use f2 probability as f2 may be forwarded.  */
    1701        96500 :             prob2 = b2->probability.invert ();
    1702              : 
    1703              :           /* Fail if the difference in probabilities is greater than 50%.
    1704              :              This rules out two well-predicted branches with opposite
    1705              :              outcomes.  */
    1706       245916 :           if (b1->probability.differs_lot_from_p (prob2))
    1707              :             {
    1708         4803 :               if (dump_file)
    1709              :                 {
    1710            0 :                   fprintf (dump_file,
    1711              :                            "Outcomes of branch in bb %i and %i differ too"
    1712              :                            " much (", bb1->index, bb2->index);
    1713            0 :                   b1->probability.dump (dump_file);
    1714            0 :                   prob2.dump (dump_file);
    1715            0 :                   fprintf (dump_file, ")\n");
    1716              :                 }
    1717         4803 :               return false;
    1718              :             }
    1719              :         }
    1720              : 
    1721       324171 :       if (dump_file && match)
    1722           16 :         fprintf (dump_file, "Conditionals in bb %i and %i match.\n",
    1723              :                  bb1->index, bb2->index);
    1724              : 
    1725       324171 :       return match;
    1726              :     }
    1727              : 
    1728              :   /* Generic case - we are seeing a computed jump, table jump or trapping
    1729              :      instruction.  */
    1730              : 
    1731              :   /* Check whether there are tablejumps in the end of BB1 and BB2.
    1732              :      Return true if they are identical.  */
    1733     12901566 :     {
    1734     12901566 :       rtx_insn *label1, *label2;
    1735     12901566 :       rtx_jump_table_data *table1, *table2;
    1736              : 
    1737     12901566 :       if (tablejump_p (BB_END (bb1), &label1, &table1)
    1738        75790 :           && tablejump_p (BB_END (bb2), &label2, &table2)
    1739     12902998 :           && GET_CODE (PATTERN (table1)) == GET_CODE (PATTERN (table2)))
    1740              :         {
    1741              :           /* The labels should never be the same rtx.  If they really are same
    1742              :              the jump tables are same too. So disable crossjumping of blocks BB1
    1743              :              and BB2 because when deleting the common insns in the end of BB1
    1744              :              by delete_basic_block () the jump table would be deleted too.  */
    1745              :           /* If LABEL2 is referenced in BB1->END do not do anything
    1746              :              because we would loose information when replacing
    1747              :              LABEL1 by LABEL2 and then LABEL2 by LABEL1 in BB1->END.  */
    1748         1432 :           if (label1 != label2 && !rtx_referenced_p (label2, BB_END (bb1)))
    1749              :             {
    1750              :               /* Set IDENTICAL to true when the tables are identical.  */
    1751         1432 :               bool identical = false;
    1752         1432 :               rtx p1, p2;
    1753              : 
    1754         1432 :               p1 = PATTERN (table1);
    1755         1432 :               p2 = PATTERN (table2);
    1756         1432 :               if (GET_CODE (p1) == ADDR_VEC && rtx_equal_p (p1, p2))
    1757              :                 {
    1758              :                   identical = true;
    1759              :                 }
    1760         1308 :               else if (GET_CODE (p1) == ADDR_DIFF_VEC
    1761          364 :                        && (XVECLEN (p1, 1) == XVECLEN (p2, 1))
    1762          258 :                        && rtx_equal_p (XEXP (p1, 2), XEXP (p2, 2))
    1763         1566 :                        && rtx_equal_p (XEXP (p1, 3), XEXP (p2, 3)))
    1764              :                 {
    1765          258 :                   int i;
    1766              : 
    1767          258 :                   identical = true;
    1768         1152 :                   for (i = XVECLEN (p1, 1) - 1; i >= 0 && identical; i--)
    1769          894 :                     if (!rtx_equal_p (XVECEXP (p1, 1, i), XVECEXP (p2, 1, i)))
    1770              :                       identical = false;
    1771              :                 }
    1772              : 
    1773          258 :               if (identical)
    1774              :                 {
    1775          172 :                   bool match;
    1776              : 
    1777              :                   /* Temporarily replace references to LABEL1 with LABEL2
    1778              :                      in BB1->END so that we could compare the instructions.  */
    1779          172 :                   replace_label_in_insn (BB_END (bb1), label1, label2, false);
    1780              : 
    1781          172 :                   match = (old_insns_match_p (mode, BB_END (bb1), BB_END (bb2))
    1782              :                            == dir_both);
    1783          172 :                   if (dump_file && match)
    1784            0 :                     fprintf (dump_file,
    1785              :                              "Tablejumps in bb %i and %i match.\n",
    1786              :                              bb1->index, bb2->index);
    1787              : 
    1788              :                   /* Set the original label in BB1->END because when deleting
    1789              :                      a block whose end is a tablejump, the tablejump referenced
    1790              :                      from the instruction is deleted too.  */
    1791          172 :                   replace_label_in_insn (BB_END (bb1), label2, label1, false);
    1792              : 
    1793         1432 :                   return match;
    1794              :                 }
    1795              :             }
    1796         1260 :           return false;
    1797              :         }
    1798              :     }
    1799              : 
    1800              :   /* Find the last non-debug non-note instruction in each bb, except
    1801              :      stop when we see the NOTE_INSN_BASIC_BLOCK, as old_insns_match_p
    1802              :      handles that case specially. old_insns_match_p does not handle
    1803              :      other types of instruction notes.  */
    1804     12900134 :   rtx_insn *last1 = BB_END (bb1);
    1805     12900134 :   rtx_insn *last2 = BB_END (bb2);
    1806     12900225 :   while (!NOTE_INSN_BASIC_BLOCK_P (last1) &&
    1807     12782616 :          (DEBUG_INSN_P (last1) || NOTE_P (last1)))
    1808           91 :     last1 = PREV_INSN (last1);
    1809     12929480 :   while (!NOTE_INSN_BASIC_BLOCK_P (last2) &&
    1810     12815160 :          (DEBUG_INSN_P (last2) || NOTE_P (last2)))
    1811        29346 :     last2 = PREV_INSN (last2);
    1812     12900134 :   gcc_assert (last1 && last2);
    1813              : 
    1814              :   /* First ensure that the instructions match.  There may be many outgoing
    1815              :      edges so this test is generally cheaper.  */
    1816     12900134 :   if (old_insns_match_p (mode, last1, last2) != dir_both)
    1817              :     return false;
    1818              : 
    1819              :   /* Search the outgoing edges, ensure that the counts do match, find possible
    1820              :      fallthru and exception handling edges since these needs more
    1821              :      validation.  */
    1822      7134816 :   if (EDGE_COUNT (bb1->succs) != EDGE_COUNT (bb2->succs))
    1823              :     return false;
    1824              : 
    1825      2378259 :   bool nonfakeedges = false;
    1826      5831956 :   FOR_EACH_EDGE (e1, ei, bb1->succs)
    1827              :     {
    1828      3453697 :       e2 = EDGE_SUCC (bb2, ei.index);
    1829              : 
    1830      3453697 :       if ((e1->flags & EDGE_FAKE) == 0)
    1831      2497234 :         nonfakeedges = true;
    1832              : 
    1833      3453697 :       if (e1->flags & EDGE_EH)
    1834      1120375 :         nehedges1++;
    1835              : 
    1836      3453697 :       if (e2->flags & EDGE_EH)
    1837      1120375 :         nehedges2++;
    1838              : 
    1839      3453697 :       if (e1->flags & EDGE_FALLTHRU)
    1840      1159967 :         fallthru1 = e1;
    1841      3453697 :       if (e2->flags & EDGE_FALLTHRU)
    1842      1159967 :         fallthru2 = e2;
    1843              :     }
    1844              : 
    1845              :   /* If number of edges of various types does not match, fail.  */
    1846      2378259 :   if (nehedges1 != nehedges2
    1847      2378259 :       || (fallthru1 != 0) != (fallthru2 != 0))
    1848              :     return false;
    1849              : 
    1850              :   /* If !ACCUMULATE_OUTGOING_ARGS, bb1 (and bb2) have no successors
    1851              :      and the last real insn doesn't have REG_ARGS_SIZE note, don't
    1852              :      attempt to optimize, as the two basic blocks might have different
    1853              :      REG_ARGS_SIZE depths.  For noreturn calls and unconditional
    1854              :      traps there should be REG_ARG_SIZE notes, they could be missing
    1855              :      for __builtin_unreachable () uses though.  */
    1856      2378259 :   if (!nonfakeedges
    1857       956463 :       && !ACCUMULATE_OUTGOING_ARGS
    1858      3334715 :       && (!INSN_P (last1)
    1859       956456 :           || !find_reg_note (last1, REG_ARGS_SIZE, NULL)))
    1860           11 :     return false;
    1861              : 
    1862              :   /* fallthru edges must be forwarded to the same destination.  */
    1863      2378248 :   if (fallthru1)
    1864              :     {
    1865      1159967 :       basic_block d1 = (FORWARDER_BLOCK_P (fallthru1->dest)
    1866      1159967 :                         ? single_succ (fallthru1->dest) : fallthru1->dest);
    1867      1159967 :       basic_block d2 = (FORWARDER_BLOCK_P (fallthru2->dest)
    1868      1159967 :                         ? single_succ (fallthru2->dest) : fallthru2->dest);
    1869              : 
    1870      1159967 :       if (d1 != d2)
    1871              :         return false;
    1872              :     }
    1873              : 
    1874              :   /* Ensure the same EH region.  */
    1875      1799967 :   {
    1876      1799967 :     rtx n1 = find_reg_note (last1, REG_EH_REGION, 0);
    1877      1799967 :     rtx n2 = find_reg_note (last2, REG_EH_REGION, 0);
    1878              : 
    1879      1799967 :     if (!n1 && n2)
    1880              :       return false;
    1881              : 
    1882      1799967 :     if (n1 && (!n2 || XEXP (n1, 0) != XEXP (n2, 0)))
    1883              :       return false;
    1884              :   }
    1885              : 
    1886              :   /* The same checks as in try_crossjump_to_edge. It is required for RTL
    1887              :      version of sequence abstraction.  */
    1888      4096449 :   FOR_EACH_EDGE (e1, ei, bb2->succs)
    1889              :     {
    1890      2296512 :       edge e2;
    1891      2296512 :       edge_iterator ei;
    1892      2296512 :       basic_block d1 = e1->dest;
    1893              : 
    1894      2296512 :       if (FORWARDER_BLOCK_P (d1))
    1895       604990 :         d1 = EDGE_SUCC (d1, 0)->dest;
    1896              : 
    1897      2794527 :       FOR_EACH_EDGE (e2, ei, bb1->succs)
    1898              :         {
    1899      2794527 :           basic_block d2 = e2->dest;
    1900      2794527 :           if (FORWARDER_BLOCK_P (d2))
    1901       782272 :             d2 = EDGE_SUCC (d2, 0)->dest;
    1902      2794527 :           if (d1 == d2)
    1903              :             break;
    1904              :         }
    1905              : 
    1906      2296512 :       if (!e2)
    1907            0 :         return false;
    1908              :     }
    1909              : 
    1910              :   return true;
    1911              : }
    1912              : 
    1913              : /* Returns true if BB basic block has a preserve label.  */
    1914              : 
    1915              : static bool
    1916       367555 : block_has_preserve_label (basic_block bb)
    1917              : {
    1918       367555 :   return (bb
    1919       367555 :           && block_label (bb)
    1920       682550 :           && LABEL_PRESERVE_P (block_label (bb)));
    1921              : }
    1922              : 
    1923              : /* E1 and E2 are edges with the same destination block.  Search their
    1924              :    predecessors for common code.  If found, redirect control flow from
    1925              :    (maybe the middle of) E1->SRC to (maybe the middle of) E2->SRC (dir_forward),
    1926              :    or the other way around (dir_backward).  DIR specifies the allowed
    1927              :    replacement direction.  */
    1928              : 
    1929              : static bool
    1930     52066898 : try_crossjump_to_edge (int mode, edge e1, edge e2,
    1931              :                        enum replace_direction dir)
    1932              : {
    1933     52066898 :   int nmatch;
    1934     52066898 :   basic_block src1 = e1->src, src2 = e2->src;
    1935     52066898 :   basic_block redirect_to, redirect_from, to_remove;
    1936     52066898 :   basic_block osrc1, osrc2, redirect_edges_to, tmp;
    1937     52066898 :   rtx_insn *newpos1, *newpos2;
    1938     52066898 :   edge s;
    1939     52066898 :   edge_iterator ei;
    1940              : 
    1941     52066898 :   newpos1 = newpos2 = NULL;
    1942              : 
    1943              :   /* Search backward through forwarder blocks.  We don't need to worry
    1944              :      about multiple entry or chained forwarders, as they will be optimized
    1945              :      away.  We do this to look past the unconditional jump following a
    1946              :      conditional jump that is required due to the current CFG shape.  */
    1947     52066898 :   if (single_pred_p (src1)
    1948     52066898 :       && FORWARDER_BLOCK_P (src1))
    1949     11896426 :     e1 = single_pred_edge (src1), src1 = e1->src;
    1950              : 
    1951     52066898 :   if (single_pred_p (src2)
    1952     52066687 :       && FORWARDER_BLOCK_P (src2))
    1953      5740764 :     e2 = single_pred_edge (src2), src2 = e2->src;
    1954              : 
    1955              :   /* Nothing to do if we reach ENTRY, or a common source block.  */
    1956     52066898 :   if (src1 == ENTRY_BLOCK_PTR_FOR_FN (cfun) || src2
    1957              :       == ENTRY_BLOCK_PTR_FOR_FN (cfun))
    1958              :     return false;
    1959     52066466 :   if (src1 == src2)
    1960              :     return false;
    1961              : 
    1962              :   /* Seeing more than 1 forwarder blocks would confuse us later...  */
    1963     52066338 :   if (FORWARDER_BLOCK_P (e1->dest)
    1964     52066338 :       && FORWARDER_BLOCK_P (single_succ (e1->dest)))
    1965              :     return false;
    1966              : 
    1967     52054579 :   if (FORWARDER_BLOCK_P (e2->dest)
    1968     52054579 :       && FORWARDER_BLOCK_P (single_succ (e2->dest)))
    1969              :     return false;
    1970              : 
    1971              :   /* Likewise with dead code (possibly newly created by the other optimizations
    1972              :      of cfg_cleanup).  */
    1973     52053953 :   if (EDGE_COUNT (src1->preds) == 0 || EDGE_COUNT (src2->preds) == 0)
    1974              :     return false;
    1975              : 
    1976              :   /* Do not turn corssing edge to non-crossing or vice versa after reload.  */
    1977     47331482 :   if (BB_PARTITION (src1) != BB_PARTITION (src2)
    1978       186992 :       && reload_completed)
    1979              :     return false;
    1980              : 
    1981              :   /* Look for the common insn sequence, part the first ...  */
    1982     47144490 :   if (!outgoing_edges_match (mode, src1, src2))
    1983              :     return false;
    1984              : 
    1985              :   /* ... and part the second.  */
    1986     16024789 :   nmatch = flow_find_cross_jump (src1, src2, &newpos1, &newpos2, &dir);
    1987              : 
    1988     16024789 :   osrc1 = src1;
    1989     16024789 :   osrc2 = src2;
    1990     16024789 :   if (newpos1 != NULL_RTX)
    1991      5113936 :     src1 = BLOCK_FOR_INSN (newpos1);
    1992     16024789 :   if (newpos2 != NULL_RTX)
    1993      5113936 :     src2 = BLOCK_FOR_INSN (newpos2);
    1994              : 
    1995              :   /* Check that SRC1 and SRC2 have preds again.  They may have changed
    1996              :      above due to the call to flow_find_cross_jump.  */
    1997     67763779 :   if (EDGE_COUNT (src1->preds) == 0 || EDGE_COUNT (src2->preds) == 0)
    1998              :     return false;
    1999              : 
    2000     16024789 :   if (dir == dir_backward)
    2001              :     {
    2002         1853 :       std::swap (osrc1, osrc2);
    2003         1853 :       std::swap (src1, src2);
    2004         1853 :       std::swap (e1, e2);
    2005         1853 :       std::swap (newpos1, newpos2);
    2006              :     }
    2007              : 
    2008              :   /* Don't proceed with the crossjump unless we found a sufficient number
    2009              :      of matching instructions or the 'from' block was totally matched
    2010              :      (such that its predecessors will hopefully be redirected and the
    2011              :      block removed).  */
    2012     16024789 :   if ((nmatch < param_min_crossjump_insns)
    2013     15898154 :       && (newpos1 != BB_HEAD (src1)))
    2014              :     return false;
    2015              : 
    2016              :   /* Avoid deleting preserve label when redirecting ABNORMAL edges.  */
    2017       367555 :   if (block_has_preserve_label (e1->dest)
    2018       367555 :       && (e1->flags & EDGE_ABNORMAL))
    2019              :     return false;
    2020              : 
    2021              :   /* Here we know that the insns in the end of SRC1 which are common with SRC2
    2022              :      will be deleted.
    2023              :      If we have tablejumps in the end of SRC1 and SRC2
    2024              :      they have been already compared for equivalence in outgoing_edges_match ()
    2025              :      so replace the references to TABLE1 by references to TABLE2.  */
    2026       327908 :   {
    2027       327908 :       rtx_insn *label1, *label2;
    2028       327908 :       rtx_jump_table_data *table1, *table2;
    2029              : 
    2030       327908 :       if (tablejump_p (BB_END (osrc1), &label1, &table1)
    2031          124 :           && tablejump_p (BB_END (osrc2), &label2, &table2)
    2032       328032 :           && label1 != label2)
    2033              :         {
    2034          124 :           rtx_insn *insn;
    2035              : 
    2036              :           /* Replace references to LABEL1 with LABEL2.  */
    2037       387514 :           for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
    2038              :             {
    2039              :               /* Do not replace the label in SRC1->END because when deleting
    2040              :                  a block whose end is a tablejump, the tablejump referenced
    2041              :                  from the instruction is deleted too.  */
    2042       387390 :               if (insn != BB_END (osrc1))
    2043       387266 :                 replace_label_in_insn (insn, label1, label2, true);
    2044              :             }
    2045              :         }
    2046              :   }
    2047              : 
    2048              :   /* Avoid splitting if possible.  We must always split when SRC2 has
    2049              :      EH predecessor edges, or we may end up with basic blocks with both
    2050              :      normal and EH predecessor edges.  */
    2051       327908 :   if (newpos2 == BB_HEAD (src2)
    2052       327908 :       && !(EDGE_PRED (src2, 0)->flags & EDGE_EH))
    2053              :     redirect_to = src2;
    2054              :   else
    2055              :     {
    2056        78296 :       if (newpos2 == BB_HEAD (src2))
    2057              :         {
    2058              :           /* Skip possible basic block header.  */
    2059         5814 :           if (LABEL_P (newpos2))
    2060         5814 :             newpos2 = NEXT_INSN (newpos2);
    2061         5814 :           while (DEBUG_INSN_P (newpos2))
    2062            0 :             newpos2 = NEXT_INSN (newpos2);
    2063         5814 :           if (NOTE_P (newpos2))
    2064         5814 :             newpos2 = NEXT_INSN (newpos2);
    2065         6009 :           while (DEBUG_INSN_P (newpos2))
    2066          195 :             newpos2 = NEXT_INSN (newpos2);
    2067              :         }
    2068              : 
    2069        78296 :       if (dump_file)
    2070            0 :         fprintf (dump_file, "Splitting bb %i before %i insns\n",
    2071              :                  src2->index, nmatch);
    2072        78296 :       redirect_to = split_block (src2, PREV_INSN (newpos2))->dest;
    2073              :     }
    2074              : 
    2075       327908 :   if (dump_file)
    2076            4 :     fprintf (dump_file,
    2077              :              "Cross jumping from bb %i to bb %i; %i common insns\n",
    2078              :              src1->index, src2->index, nmatch);
    2079              : 
    2080              :   /* We may have some registers visible through the block.  */
    2081       327908 :   df_set_bb_dirty (redirect_to);
    2082              : 
    2083       327908 :   if (osrc2 == src2)
    2084              :     redirect_edges_to = redirect_to;
    2085              :   else
    2086        10903 :     redirect_edges_to = osrc2;
    2087              : 
    2088              :   /* Recompute the counts of destinations of outgoing edges.  */
    2089       725094 :   FOR_EACH_EDGE (s, ei, redirect_edges_to->succs)
    2090              :     {
    2091       397186 :       edge s2;
    2092       397186 :       edge_iterator ei;
    2093       397186 :       basic_block d = s->dest;
    2094              : 
    2095       397186 :       if (FORWARDER_BLOCK_P (d))
    2096        29763 :         d = single_succ (d);
    2097              : 
    2098       472098 :       FOR_EACH_EDGE (s2, ei, src1->succs)
    2099              :         {
    2100       472098 :           basic_block d2 = s2->dest;
    2101       472098 :           if (FORWARDER_BLOCK_P (d2))
    2102       100554 :             d2 = single_succ (d2);
    2103       472098 :           if (d == d2)
    2104              :             break;
    2105              :         }
    2106              : 
    2107              :       /* Take care to update possible forwarder blocks.  We verified
    2108              :          that there is no more than one in the chain, so we can't run
    2109              :          into infinite loop.  */
    2110       397186 :       if (FORWARDER_BLOCK_P (s->dest))
    2111        29763 :         s->dest->count += s->count ();
    2112              : 
    2113       397186 :       if (FORWARDER_BLOCK_P (s2->dest))
    2114        77324 :         s2->dest->count -= s->count ();
    2115              : 
    2116       397186 :       s->probability = s->probability.combine_with_count
    2117       397186 :                           (redirect_edges_to->count,
    2118              :                            s2->probability, src1->count);
    2119              :     }
    2120              : 
    2121              :   /* Adjust count for the block.  An earlier jump
    2122              :      threading pass may have left the profile in an inconsistent
    2123              :      state (see update_bb_profile_for_threading) so we must be
    2124              :      prepared for overflows.  */
    2125              :   tmp = redirect_to;
    2126       350964 :   do
    2127              :     {
    2128       339436 :       tmp->count += src1->count;
    2129       339436 :       if (tmp == redirect_edges_to)
    2130              :         break;
    2131        11528 :       tmp = find_fallthru_edge (tmp->succs)->dest;
    2132              :     }
    2133              :   while (true);
    2134       327908 :   update_br_prob_note (redirect_edges_to);
    2135              : 
    2136              :   /* Edit SRC1 to go to REDIRECT_TO at NEWPOS1.  */
    2137              : 
    2138              :   /* Skip possible basic block header.  */
    2139       327908 :   if (LABEL_P (newpos1))
    2140       129648 :     newpos1 = NEXT_INSN (newpos1);
    2141              : 
    2142       344262 :   while (DEBUG_INSN_P (newpos1))
    2143        16354 :     newpos1 = NEXT_INSN (newpos1);
    2144              : 
    2145       327908 :   if (NOTE_INSN_BASIC_BLOCK_P (newpos1))
    2146       243273 :     newpos1 = NEXT_INSN (newpos1);
    2147              : 
    2148              :   /* Skip also prologue and function markers.  */
    2149       837751 :   while (DEBUG_INSN_P (newpos1)
    2150       837751 :          || (NOTE_P (newpos1)
    2151        13938 :              && (NOTE_KIND (newpos1) == NOTE_INSN_PROLOGUE_END
    2152        13938 :                  || NOTE_KIND (newpos1) == NOTE_INSN_FUNCTION_BEG)))
    2153       509843 :     newpos1 = NEXT_INSN (newpos1);
    2154              : 
    2155       327908 :   redirect_from = split_block (src1, PREV_INSN (newpos1))->src;
    2156       327908 :   to_remove = single_succ (redirect_from);
    2157              : 
    2158       327908 :   redirect_edge_and_branch_force (single_succ_edge (redirect_from), redirect_to);
    2159       327908 :   delete_basic_block (to_remove);
    2160              : 
    2161       327908 :   update_forwarder_flag (redirect_from);
    2162       327908 :   if (redirect_to != src2)
    2163        78296 :     update_forwarder_flag (src2);
    2164              : 
    2165              :   return true;
    2166              : }
    2167              : 
    2168              : /* Search the predecessors of BB for common insn sequences.  When found,
    2169              :    share code between them by redirecting control flow.  Return true if
    2170              :    any changes made.  */
    2171              : 
    2172              : static bool
    2173     30993471 : try_crossjump_bb (int mode, basic_block bb)
    2174              : {
    2175     30993471 :   edge e, e2, fallthru;
    2176     30993471 :   bool changed;
    2177     30993471 :   unsigned max, ix, ix2;
    2178              : 
    2179              :   /* Nothing to do if there is not at least two incoming edges.  */
    2180     31217151 :   if (EDGE_COUNT (bb->preds) < 2)
    2181              :     return false;
    2182              : 
    2183              :   /* Don't crossjump if this block ends in a computed jump,
    2184              :      unless we are optimizing for size.  */
    2185      8499848 :   if (optimize_bb_for_size_p (bb)
    2186      1360566 :       && bb != EXIT_BLOCK_PTR_FOR_FN (cfun)
    2187      9820114 :       && computed_jump_p (BB_END (bb)))
    2188              :     return false;
    2189              : 
    2190              :   /* If we are partitioning hot/cold basic blocks, we don't want to
    2191              :      mess up unconditional or indirect jumps that cross between hot
    2192              :      and cold sections.
    2193              : 
    2194              :      Basic block partitioning may result in some jumps that appear to
    2195              :      be optimizable (or blocks that appear to be mergeable), but which really
    2196              :      must be left untouched (they are required to make it safely across
    2197              :      partition boundaries).  See the comments at the top of
    2198              :      bb-reorder.cc:partition_hot_cold_basic_blocks for complete details.  */
    2199              : 
    2200      8499818 :   if (BB_PARTITION (EDGE_PRED (bb, 0)->src) !=
    2201      8499818 :                                         BB_PARTITION (EDGE_PRED (bb, 1)->src)
    2202      8499818 :       || (EDGE_PRED (bb, 0)->flags & EDGE_CROSSING))
    2203              :     return false;
    2204              : 
    2205              :   /* It is always cheapest to redirect a block that ends in a branch to
    2206              :      a block that falls through into BB, as that adds no branches to the
    2207              :      program.  We'll try that combination first.  */
    2208      8279030 :   fallthru = NULL;
    2209      8279030 :   max = param_max_crossjump_edges;
    2210              : 
    2211      8279030 :   if (EDGE_COUNT (bb->preds) > max)
    2212              :     return false;
    2213              : 
    2214      8276168 :   fallthru = find_fallthru_edge (bb->preds);
    2215              : 
    2216      8276168 :   changed = false;
    2217     40627866 :   for (ix = 0; ix < EDGE_COUNT (bb->preds);)
    2218              :     {
    2219     24075530 :       e = EDGE_PRED (bb, ix);
    2220     24075530 :       ix++;
    2221              : 
    2222              :       /* As noted above, first try with the fallthru predecessor (or, a
    2223              :          fallthru predecessor if we are in cfglayout mode).  */
    2224     24075530 :       if (fallthru)
    2225              :         {
    2226              :           /* Don't combine the fallthru edge into anything else.
    2227              :              If there is a match, we'll do it the other way around.  */
    2228     17638413 :           if (e == fallthru)
    2229      6662513 :             continue;
    2230              :           /* If nothing changed since the last attempt, there is nothing
    2231              :              we can do.  */
    2232     10975900 :           if (!first_pass
    2233      4401388 :               && !((e->src->flags & BB_MODIFIED)
    2234      3530123 :                    || (fallthru->src->flags & BB_MODIFIED)))
    2235      3150371 :             continue;
    2236              : 
    2237      7825529 :           if (try_crossjump_to_edge (mode, e, fallthru, dir_forward))
    2238              :             {
    2239       141358 :               changed = true;
    2240       141358 :               ix = 0;
    2241       141358 :               continue;
    2242              :             }
    2243              :         }
    2244              : 
    2245              :       /* Non-obvious work limiting check: Recognize that we're going
    2246              :          to call try_crossjump_bb on every basic block.  So if we have
    2247              :          two blocks with lots of outgoing edges (a switch) and they
    2248              :          share lots of common destinations, then we would do the
    2249              :          cross-jump check once for each common destination.
    2250              : 
    2251              :          Now, if the blocks actually are cross-jump candidates, then
    2252              :          all of their destinations will be shared.  Which means that
    2253              :          we only need check them for cross-jump candidacy once.  We
    2254              :          can eliminate redundant checks of crossjump(A,B) by arbitrarily
    2255              :          choosing to do the check from the block for which the edge
    2256              :          in question is the first successor of A.  */
    2257     14121288 :       if (EDGE_SUCC (e->src, 0) != e)
    2258      2861001 :         continue;
    2259              : 
    2260    171266145 :       for (ix2 = 0; ix2 < EDGE_COUNT (bb->preds); ix2++)
    2261              :         {
    2262    127840710 :           e2 = EDGE_PRED (bb, ix2);
    2263              : 
    2264    127840710 :           if (e2 == e)
    2265     11172028 :             continue;
    2266              : 
    2267              :           /* We've already checked the fallthru edge above.  */
    2268    116668682 :           if (e2 == fallthru)
    2269      6156218 :             continue;
    2270              : 
    2271              :           /* The "first successor" check above only prevents multiple
    2272              :              checks of crossjump(A,B).  In order to prevent redundant
    2273              :              checks of crossjump(B,A), require that A be the block
    2274              :              with the lowest index.  */
    2275    110512464 :           if (e->src->index > e2->src->index)
    2276     55325662 :             continue;
    2277              : 
    2278              :           /* If nothing changed since the last attempt, there is nothing
    2279              :              we can do.  */
    2280     55186802 :           if (!first_pass
    2281     14248316 :               && !((e->src->flags & BB_MODIFIED)
    2282     11814948 :                    || (e2->src->flags & BB_MODIFIED)))
    2283     10945433 :             continue;
    2284              : 
    2285              :           /* Both e and e2 are not fallthru edges, so we can crossjump in either
    2286              :              direction.  */
    2287     44241369 :           if (try_crossjump_to_edge (mode, e, e2, dir_both))
    2288              :             {
    2289              :               changed = true;
    2290              :               ix = 0;
    2291              :               break;
    2292              :             }
    2293              :         }
    2294              :     }
    2295              : 
    2296      8276168 :   if (changed)
    2297       155535 :     crossjumps_occurred = true;
    2298              : 
    2299              :   return changed;
    2300              : }
    2301              : 
    2302              : /* Search the successors of BB for common insn sequences.  When found,
    2303              :    share code between them by moving it across the basic block
    2304              :    boundary.  Return true if any changes made.  */
    2305              : 
    2306              : static bool
    2307     29785841 : try_head_merge_bb (basic_block bb)
    2308              : {
    2309     29785841 :   basic_block final_dest_bb = NULL;
    2310     29785841 :   int max_match = INT_MAX;
    2311     29785841 :   edge e0;
    2312     29785841 :   rtx_insn **headptr, **currptr, **nextptr;
    2313     29785841 :   bool changed, moveall;
    2314     29785841 :   unsigned ix;
    2315     29785841 :   rtx_insn *e0_last_head;
    2316     29785841 :   rtx cond;
    2317     29785841 :   rtx_insn *move_before;
    2318     29785841 :   unsigned nedges = EDGE_COUNT (bb->succs);
    2319     29785841 :   rtx_insn *jump = BB_END (bb);
    2320     29785841 :   regset live, live_union;
    2321              : 
    2322              :   /* Nothing to do if there is not at least two outgoing edges.  */
    2323     29785841 :   if (nedges < 2)
    2324              :     return false;
    2325              : 
    2326              :   /* Don't crossjump if this block ends in a computed jump,
    2327              :      unless we are optimizing for size.  */
    2328     15296538 :   if (optimize_bb_for_size_p (bb)
    2329      1759681 :       && bb != EXIT_BLOCK_PTR_FOR_FN (cfun)
    2330     17056219 :       && computed_jump_p (BB_END (bb)))
    2331              :     return false;
    2332              : 
    2333     15296510 :   cond = get_condition (jump, &move_before, true, false);
    2334     15296510 :   if (cond == NULL_RTX)
    2335      2106698 :     move_before = jump;
    2336              : 
    2337     46156669 :   for (ix = 0; ix < nedges; ix++)
    2338     30860159 :     if (EDGE_SUCC (bb, ix)->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
    2339              :       return false;
    2340              : 
    2341     28419204 :   for (ix = 0; ix < nedges; ix++)
    2342              :     {
    2343     23758106 :       edge e = EDGE_SUCC (bb, ix);
    2344     23758106 :       basic_block other_bb = e->dest;
    2345              : 
    2346     23758106 :       if (df_get_bb_dirty (other_bb))
    2347              :         {
    2348       547639 :           block_was_dirty = true;
    2349       547639 :           return false;
    2350              :         }
    2351              : 
    2352     23210467 :       if (e->flags & EDGE_ABNORMAL)
    2353              :         return false;
    2354              : 
    2355              :       /* Normally, all destination blocks must only be reachable from this
    2356              :          block, i.e. they must have one incoming edge.
    2357              : 
    2358              :          There is one special case we can handle, that of multiple consecutive
    2359              :          jumps where the first jumps to one of the targets of the second jump.
    2360              :          This happens frequently in switch statements for default labels.
    2361              :          The structure is as follows:
    2362              :          FINAL_DEST_BB
    2363              :          ....
    2364              :          if (cond) jump A;
    2365              :          fall through
    2366              :          BB
    2367              :          jump with targets A, B, C, D...
    2368              :          A
    2369              :          has two incoming edges, from FINAL_DEST_BB and BB
    2370              : 
    2371              :          In this case, we can try to move the insns through BB and into
    2372              :          FINAL_DEST_BB.  */
    2373     21180662 :       if (EDGE_COUNT (other_bb->preds) != 1)
    2374              :         {
    2375      8423589 :           edge incoming_edge, incoming_bb_other_edge;
    2376      8423589 :           edge_iterator ei;
    2377              : 
    2378      8423589 :           if (final_dest_bb != NULL
    2379      8423589 :               || EDGE_COUNT (other_bb->preds) != 2)
    2380      8057968 :             return false;
    2381              : 
    2382              :           /* We must be able to move the insns across the whole block.  */
    2383      4637010 :           move_before = BB_HEAD (bb);
    2384     31781908 :           while (!NONDEBUG_INSN_P (move_before))
    2385     27144898 :             move_before = NEXT_INSN (move_before);
    2386              : 
    2387      4637010 :           if (EDGE_COUNT (bb->preds) != 1)
    2388              :             return false;
    2389      2770812 :           incoming_edge = EDGE_PRED (bb, 0);
    2390      2770812 :           final_dest_bb = incoming_edge->src;
    2391     10347325 :           if (EDGE_COUNT (final_dest_bb->succs) != 2)
    2392              :             return false;
    2393      3282178 :           FOR_EACH_EDGE (incoming_bb_other_edge, ei, final_dest_bb->succs)
    2394      3282178 :             if (incoming_bb_other_edge != incoming_edge)
    2395              :               break;
    2396      2289357 :           if (incoming_bb_other_edge->dest != other_bb)
    2397              :             return false;
    2398              :         }
    2399              :     }
    2400              : 
    2401      4661098 :   e0 = EDGE_SUCC (bb, 0);
    2402      4661098 :   e0_last_head = NULL;
    2403      4661098 :   changed = false;
    2404              : 
    2405      4780279 :   for (ix = 1; ix < nedges; ix++)
    2406              :     {
    2407      4665431 :       edge e = EDGE_SUCC (bb, ix);
    2408      4665431 :       rtx_insn *e0_last, *e_last;
    2409      4665431 :       int nmatch;
    2410              : 
    2411      4665431 :       nmatch = flow_find_head_matching_sequence (e0->dest, e->dest,
    2412              :                                                  &e0_last, &e_last, 0);
    2413      4665431 :       if (nmatch == 0)
    2414      4546250 :         return false;
    2415              : 
    2416       119181 :       if (nmatch < max_match)
    2417              :         {
    2418       115666 :           max_match = nmatch;
    2419       115666 :           e0_last_head = e0_last;
    2420              :         }
    2421              :     }
    2422              : 
    2423              :   /* If we matched an entire block, we probably have to avoid moving the
    2424              :      last insn.  */
    2425       114848 :   if (max_match > 0
    2426       114848 :       && e0_last_head == BB_END (e0->dest)
    2427       123762 :       && (find_reg_note (e0_last_head, REG_EH_REGION, 0)
    2428         7286 :           || control_flow_insn_p (e0_last_head)))
    2429              :     {
    2430         1640 :       max_match--;
    2431         1640 :       if (max_match == 0)
    2432              :         return false;
    2433          258 :       e0_last_head = prev_real_nondebug_insn (e0_last_head);
    2434              :     }
    2435              : 
    2436       113466 :   if (max_match == 0)
    2437              :     return false;
    2438              : 
    2439              :   /* We must find a union of the live registers at each of the end points.  */
    2440       113466 :   live = BITMAP_ALLOC (NULL);
    2441       113466 :   live_union = BITMAP_ALLOC (NULL);
    2442              : 
    2443       113466 :   currptr = XNEWVEC (rtx_insn *, nedges);
    2444       113466 :   headptr = XNEWVEC (rtx_insn *, nedges);
    2445       113466 :   nextptr = XNEWVEC (rtx_insn *, nedges);
    2446              : 
    2447       343786 :   for (ix = 0; ix < nedges; ix++)
    2448              :     {
    2449       230320 :       int j;
    2450       230320 :       basic_block merge_bb = EDGE_SUCC (bb, ix)->dest;
    2451       230320 :       rtx_insn *head = BB_HEAD (merge_bb);
    2452              : 
    2453      1512040 :       while (!NONDEBUG_INSN_P (head))
    2454      1281720 :         head = NEXT_INSN (head);
    2455       230320 :       headptr[ix] = head;
    2456       230320 :       currptr[ix] = head;
    2457              : 
    2458              :       /* Compute the end point and live information  */
    2459       371182 :       for (j = 1; j < max_match; j++)
    2460       201610 :         do
    2461       201610 :           head = NEXT_INSN (head);
    2462       201610 :         while (!NONDEBUG_INSN_P (head));
    2463       230320 :       simulate_backwards_to_point (merge_bb, live, head);
    2464       230320 :       IOR_REG_SET (live_union, live);
    2465              :     }
    2466              : 
    2467              :   /* If we're moving across two blocks, verify the validity of the
    2468              :      first move, then adjust the target and let the loop below deal
    2469              :      with the final move.  */
    2470       113466 :   if (final_dest_bb != NULL)
    2471              :     {
    2472         7060 :       rtx_insn *move_upto;
    2473              : 
    2474         7060 :       moveall = can_move_insns_across (currptr[0], e0_last_head, move_before,
    2475              :                                        jump, e0->dest, live_union,
    2476              :                                        NULL, &move_upto);
    2477         7060 :       if (!moveall)
    2478              :         {
    2479         5487 :           if (move_upto == NULL_RTX)
    2480         5097 :             goto out;
    2481              : 
    2482         1244 :           while (e0_last_head != move_upto)
    2483              :             {
    2484          854 :               df_simulate_one_insn_backwards (e0->dest, e0_last_head,
    2485              :                                               live_union);
    2486          854 :               e0_last_head = PREV_INSN (e0_last_head);
    2487              :             }
    2488              :         }
    2489         1963 :       if (e0_last_head == NULL_RTX)
    2490            0 :         goto out;
    2491              : 
    2492         1963 :       jump = BB_END (final_dest_bb);
    2493         1963 :       cond = get_condition (jump, &move_before, true, false);
    2494         1963 :       if (cond == NULL_RTX)
    2495            0 :         move_before = jump;
    2496              :     }
    2497              : 
    2498       186414 :   do
    2499              :     {
    2500       186414 :       rtx_insn *move_upto;
    2501       186414 :       moveall = can_move_insns_across (currptr[0], e0_last_head,
    2502              :                                        move_before, jump, e0->dest, live_union,
    2503              :                                        NULL, &move_upto);
    2504       186414 :       if (!moveall && move_upto == NULL_RTX)
    2505              :         {
    2506       147092 :           if (jump == move_before)
    2507              :             break;
    2508              : 
    2509              :           /* Try again, using a different insertion point.  */
    2510        74229 :           move_before = jump;
    2511              : 
    2512        74229 :           continue;
    2513              :         }
    2514              : 
    2515        39322 :       if (final_dest_bb && !moveall)
    2516              :         /* We haven't checked whether a partial move would be OK for the first
    2517              :            move, so we have to fail this case.  */
    2518              :         break;
    2519              : 
    2520        58833 :       changed = true;
    2521        58833 :       for (;;)
    2522              :         {
    2523        58833 :           if (currptr[0] == move_upto)
    2524              :             break;
    2525        58882 :           for (ix = 0; ix < nedges; ix++)
    2526              :             {
    2527        39275 :               rtx_insn *curr = currptr[ix];
    2528        61835 :               do
    2529        61835 :                 curr = NEXT_INSN (curr);
    2530        61835 :               while (!NONDEBUG_INSN_P (curr));
    2531        39275 :               currptr[ix] = curr;
    2532              :             }
    2533              :         }
    2534              : 
    2535              :       /* If we can't currently move all of the identical insns, remember
    2536              :          each insn after the range that we'll merge.  */
    2537        39226 :       if (!moveall)
    2538        15381 :         for (ix = 0; ix < nedges; ix++)
    2539              :           {
    2540        10268 :             rtx_insn *curr = currptr[ix];
    2541        14218 :             do
    2542        14218 :               curr = NEXT_INSN (curr);
    2543        14218 :             while (!NONDEBUG_INSN_P (curr));
    2544        10268 :             nextptr[ix] = curr;
    2545              :           }
    2546              : 
    2547        39226 :       reorder_insns (headptr[0], currptr[0], PREV_INSN (move_before));
    2548        39226 :       df_set_bb_dirty (EDGE_SUCC (bb, 0)->dest);
    2549        39226 :       if (final_dest_bb != NULL)
    2550         1862 :         df_set_bb_dirty (final_dest_bb);
    2551        39226 :       df_set_bb_dirty (bb);
    2552       118883 :       for (ix = 1; ix < nedges; ix++)
    2553              :         {
    2554        40431 :           df_set_bb_dirty (EDGE_SUCC (bb, ix)->dest);
    2555        40431 :           delete_insn_chain (headptr[ix], currptr[ix], false);
    2556              :         }
    2557        39226 :       if (!moveall)
    2558              :         {
    2559         5113 :           if (jump == move_before)
    2560              :             break;
    2561              : 
    2562              :           /* For the unmerged insns, try a different insertion point.  */
    2563         3816 :           move_before = jump;
    2564              : 
    2565        11448 :           for (ix = 0; ix < nedges; ix++)
    2566         7632 :             currptr[ix] = headptr[ix] = nextptr[ix];
    2567              :         }
    2568              :     }
    2569       112158 :   while (!moveall);
    2570              : 
    2571        34113 :  out:
    2572       113466 :   free (currptr);
    2573       113466 :   free (headptr);
    2574       113466 :   free (nextptr);
    2575              : 
    2576       113466 :   crossjumps_occurred |= changed;
    2577              : 
    2578       113466 :   return changed;
    2579              : }
    2580              : 
    2581              : /* Return true if BB contains just bb note, or bb note followed
    2582              :    by only DEBUG_INSNs.  */
    2583              : 
    2584              : static bool
    2585     16602479 : trivially_empty_bb_p (basic_block bb)
    2586              : {
    2587     16602479 :   rtx_insn *insn = BB_END (bb);
    2588              : 
    2589         5598 :   while (1)
    2590              :     {
    2591     16608077 :       if (insn == BB_HEAD (bb))
    2592              :         return true;
    2593     16607160 :       if (!DEBUG_INSN_P (insn))
    2594              :         return false;
    2595         5598 :       insn = PREV_INSN (insn);
    2596              :     }
    2597              : }
    2598              : 
    2599              : /* Return true if BB contains just a return and possibly a USE of the
    2600              :    return value.  Fill in *RET and *USE with the return and use insns
    2601              :    if any found, otherwise NULL.  All CLOBBERs are ignored.  */
    2602              : 
    2603              : bool
    2604    407645054 : bb_is_just_return (basic_block bb, rtx_insn **ret, rtx_insn **use)
    2605              : {
    2606    407645054 :   *ret = *use = NULL;
    2607    407645054 :   rtx_insn *insn;
    2608              : 
    2609    407645054 :   if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
    2610              :     return false;
    2611              : 
    2612    541823425 :   FOR_BB_INSNS_REVERSE (bb, insn)
    2613    528390695 :     if (NONDEBUG_INSN_P (insn))
    2614              :       {
    2615    403189131 :         rtx pat = PATTERN (insn);
    2616              : 
    2617    403189131 :         if (!*ret && ANY_RETURN_P (pat))
    2618      7479176 :           *ret = insn;
    2619      7830956 :         else if (*ret && !*use && GET_CODE (pat) == USE
    2620      1136192 :             && REG_P (XEXP (pat, 0))
    2621    396846147 :             && REG_FUNCTION_VALUE_P (XEXP (pat, 0)))
    2622      1132978 :           *use = insn;
    2623    394576977 :         else if (GET_CODE (pat) != CLOBBER)
    2624              :           return false;
    2625              :       }
    2626              : 
    2627     13432730 :   return !!*ret;
    2628              : }
    2629              : 
    2630              : /* Do simple CFG optimizations - basic block merging, simplifying of jump
    2631              :    instructions etc.  Return nonzero if changes were made.  */
    2632              : 
    2633              : static bool
    2634     22109724 : try_optimize_cfg (int mode)
    2635              : {
    2636     22109724 :   bool changed_overall = false;
    2637     22109724 :   bool changed;
    2638     22109724 :   int iterations = 0;
    2639     22109724 :   basic_block bb, b, next;
    2640              : 
    2641     22109724 :   if (mode & (CLEANUP_CROSSJUMP | CLEANUP_THREADING))
    2642      3018296 :     clear_bb_flags ();
    2643              : 
    2644     22109724 :   crossjumps_occurred = false;
    2645              : 
    2646    322175717 :   FOR_EACH_BB_FN (bb, cfun)
    2647    300065993 :     update_forwarder_flag (bb);
    2648              : 
    2649     22109724 :   if (! targetm.cannot_modify_jumps_p ())
    2650              :     {
    2651     22109724 :       first_pass = true;
    2652              :       /* Attempt to merge blocks as made possible by edge removal.  If
    2653              :          a block has only one successor, and the successor has only
    2654              :          one predecessor, they may be combined.  */
    2655     51988392 :       do
    2656              :         {
    2657     25994196 :           block_was_dirty = false;
    2658     25994196 :           changed = false;
    2659     25994196 :           iterations++;
    2660              : 
    2661     25994196 :           if (dump_file)
    2662         1771 :             fprintf (dump_file,
    2663              :                      "\n\ntry_optimize_cfg iteration %i\n\n",
    2664              :                      iterations);
    2665              : 
    2666     25994196 :           for (b = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; b
    2667    435894840 :                != EXIT_BLOCK_PTR_FOR_FN (cfun);)
    2668              :             {
    2669    409900644 :               basic_block c;
    2670    409900644 :               edge s;
    2671    409900644 :               bool changed_here = false;
    2672              : 
    2673              :               /* Delete trivially dead basic blocks.  This is either
    2674              :                  blocks with no predecessors, or empty blocks with no
    2675              :                  successors.  However if the empty block with no
    2676              :                  successors is the successor of the ENTRY_BLOCK, it is
    2677              :                  kept.  This ensures that the ENTRY_BLOCK will have a
    2678              :                  successor which is a precondition for many RTL
    2679              :                  passes.  Empty blocks may result from expanding
    2680              :                  __builtin_unreachable ().  */
    2681    409900644 :               if (EDGE_COUNT (b->preds) == 0
    2682    409900644 :                   || (EDGE_COUNT (b->succs) == 0
    2683     16602479 :                       && trivially_empty_bb_p (b)
    2684          917 :                       && single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))->dest
    2685              :                       != b))
    2686              :                 {
    2687      5553885 :                   c = b->prev_bb;
    2688      5553885 :                   if (EDGE_COUNT (b->preds) > 0)
    2689              :                     {
    2690          917 :                       edge e;
    2691          917 :                       edge_iterator ei;
    2692              : 
    2693          917 :                       if (current_ir_type () == IR_RTL_CFGLAYOUT)
    2694              :                         {
    2695           51 :                           rtx_insn *insn;
    2696           51 :                           for (insn = BB_FOOTER (b);
    2697           51 :                                insn; insn = NEXT_INSN (insn))
    2698           51 :                             if (BARRIER_P (insn))
    2699              :                               break;
    2700           51 :                           if (insn)
    2701          102 :                             FOR_EACH_EDGE (e, ei, b->preds)
    2702           51 :                               if ((e->flags & EDGE_FALLTHRU))
    2703              :                                 {
    2704           51 :                                   if (BB_FOOTER (b)
    2705           51 :                                       && BB_FOOTER (e->src) == NULL)
    2706              :                                     {
    2707           51 :                                       BB_FOOTER (e->src) = BB_FOOTER (b);
    2708           51 :                                       BB_FOOTER (b) = NULL;
    2709              :                                     }
    2710              :                                   else
    2711            0 :                                     emit_barrier_after_bb (e->src);
    2712              :                                 }
    2713              :                         }
    2714              :                       else
    2715              :                         {
    2716          866 :                           rtx_insn *last = get_last_bb_insn (b);
    2717          866 :                           if (last && BARRIER_P (last))
    2718         1732 :                             FOR_EACH_EDGE (e, ei, b->preds)
    2719          866 :                               if ((e->flags & EDGE_FALLTHRU))
    2720          866 :                                 emit_barrier_after (BB_END (e->src));
    2721              :                         }
    2722              :                     }
    2723      5553885 :                   delete_basic_block (b);
    2724      5553885 :                   changed = true;
    2725              :                   /* Avoid trying to remove the exit block.  */
    2726      5553885 :                   b = (c == ENTRY_BLOCK_PTR_FOR_FN (cfun) ? c->next_bb : c);
    2727      5691068 :                   continue;
    2728      5553885 :                 }
    2729              : 
    2730              :               /* Remove code labels no longer used.  */
    2731    404346759 :               if (single_pred_p (b)
    2732    293982749 :                   && (single_pred_edge (b)->flags & EDGE_FALLTHRU)
    2733    207125701 :                   && !(single_pred_edge (b)->flags & EDGE_COMPLEX)
    2734    204009446 :                   && LABEL_P (BB_HEAD (b))
    2735       850215 :                   && !LABEL_PRESERVE_P (BB_HEAD (b))
    2736              :                   /* If the previous block ends with a branch to this
    2737              :                      block, we can't delete the label.  Normally this
    2738              :                      is a condjump that is yet to be simplified, but
    2739              :                      if CASE_DROPS_THRU, this can be a tablejump with
    2740              :                      some element going to the same place as the
    2741              :                      default (fallthru).  */
    2742    405181888 :                   && (single_pred (b) == ENTRY_BLOCK_PTR_FOR_FN (cfun)
    2743       835075 :                       || !JUMP_P (BB_END (single_pred (b)))
    2744       637083 :                       || ! label_is_jump_target_p (BB_HEAD (b),
    2745       637083 :                                                    BB_END (single_pred (b)))))
    2746              :                 {
    2747       828858 :                   delete_insn (BB_HEAD (b));
    2748       828858 :                   if (dump_file)
    2749           37 :                     fprintf (dump_file, "Deleted label in block %i.\n",
    2750              :                              b->index);
    2751              :                 }
    2752              : 
    2753              :               /* If we fall through an empty block, we can remove it.  */
    2754    404483942 :               if (!(mode & (CLEANUP_CFGLAYOUT | CLEANUP_NO_INSN_DEL))
    2755     86417288 :                   && single_pred_p (b)
    2756     63937558 :                   && (single_pred_edge (b)->flags & EDGE_FALLTHRU)
    2757     45173389 :                   && !LABEL_P (BB_HEAD (b))
    2758     44807138 :                   && FORWARDER_BLOCK_P (b)
    2759              :                   /* Note that forwarder_block_p true ensures that
    2760              :                      there is a successor for this block.  */
    2761      5431895 :                   && (single_succ_edge (b)->flags & EDGE_FALLTHRU)
    2762    404570204 :                   && n_basic_blocks_for_fn (cfun) > NUM_FIXED_BLOCKS + 1)
    2763              :                 {
    2764       137183 :                   if (dump_file)
    2765           11 :                     fprintf (dump_file,
    2766              :                              "Deleting fallthru block %i.\n",
    2767              :                              b->index);
    2768              : 
    2769         2664 :                   c = ((b->prev_bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
    2770       137183 :                        ? b->next_bb : b->prev_bb);
    2771       137183 :                   redirect_edge_succ_nodup (single_pred_edge (b),
    2772              :                                             single_succ (b));
    2773       137183 :                   delete_basic_block (b);
    2774       137183 :                   changed = true;
    2775       137183 :                   b = c;
    2776       137183 :                   continue;
    2777              :                 }
    2778              : 
    2779              :               /* Merge B with its single successor, if any.  */
    2780    404209576 :               if (single_succ_p (b)
    2781    177106914 :                   && (s = single_succ_edge (b))
    2782    177106914 :                   && !(s->flags & EDGE_COMPLEX)
    2783    168073139 :                   && (c = s->dest) != EXIT_BLOCK_PTR_FOR_FN (cfun)
    2784    413330844 :                   && single_pred_p (c)
    2785    411629656 :                   && b != c)
    2786              :                 {
    2787              :                   /* When not in cfg_layout mode use code aware of reordering
    2788              :                      INSN.  This code possibly creates new basic blocks so it
    2789              :                      does not fit merge_blocks interface and is kept here in
    2790              :                      hope that it will become useless once more of compiler
    2791              :                      is transformed to use cfg_layout mode.  */
    2792              : 
    2793      9121268 :                   if ((mode & CLEANUP_CFGLAYOUT)
    2794      9121268 :                       && can_merge_blocks_p (b, c))
    2795              :                     {
    2796       819330 :                       merge_blocks (b, c);
    2797       819330 :                       update_forwarder_flag (b);
    2798       819330 :                       changed_here = true;
    2799              :                     }
    2800      8301938 :                   else if (!(mode & CLEANUP_CFGLAYOUT)
    2801              :                            /* If the jump insn has side effects,
    2802              :                               we can't kill the edge.  */
    2803      7024848 :                            && (!JUMP_P (BB_END (b))
    2804      2367148 :                                || (reload_completed
    2805      3222182 :                                    ? simplejump_p (BB_END (b))
    2806       855034 :                                    : (onlyjump_p (BB_END (b))
    2807       854217 :                                       && !tablejump_p (BB_END (b),
    2808              :                                                        NULL, NULL))))
    2809     18546986 :                            && (next = merge_blocks_move (s, b, c, mode)))
    2810              :                       {
    2811              :                         b = next;
    2812              :                         changed_here = true;
    2813              :                       }
    2814              :                 }
    2815              : 
    2816              :               /* Try to change a branch to a return to just that return.  */
    2817    404209576 :               rtx_insn *ret, *use;
    2818    404209576 :               if (single_succ_p (b)
    2819    175446581 :                   && onlyjump_p (BB_END (b))
    2820    431943054 :                   && bb_is_just_return (single_succ (b), &ret, &use))
    2821              :                 {
    2822        37528 :                   if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)),
    2823        37528 :                                      PATTERN (ret), 0))
    2824              :                     {
    2825        37528 :                       if (use)
    2826        22138 :                         emit_insn_before (copy_insn (PATTERN (use)),
    2827        22138 :                                           BB_END (b));
    2828        37528 :                       if (dump_file)
    2829           23 :                         fprintf (dump_file, "Changed jump %d->%d to return.\n",
    2830           23 :                                  b->index, single_succ (b)->index);
    2831        37528 :                       redirect_edge_succ (single_succ_edge (b),
    2832        37528 :                                           EXIT_BLOCK_PTR_FOR_FN (cfun));
    2833        37528 :                       single_succ_edge (b)->flags &= ~EDGE_CROSSING;
    2834        37528 :                       changed_here = true;
    2835              :                     }
    2836              :                 }
    2837              : 
    2838              :               /* Try to change a conditional branch to a return to the
    2839              :                  respective conditional return.  */
    2840    404209576 :               if (EDGE_COUNT (b->succs) == 2
    2841    211726206 :                   && any_condjump_p (BB_END (b))
    2842    589435886 :                   && bb_is_just_return (BRANCH_EDGE (b)->dest, &ret, &use))
    2843              :                 {
    2844       590697 :                   if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)),
    2845       590697 :                                      PATTERN (ret), 0))
    2846              :                     {
    2847            0 :                       if (use)
    2848            0 :                         emit_insn_before (copy_insn (PATTERN (use)),
    2849            0 :                                           BB_END (b));
    2850            0 :                       if (dump_file)
    2851            0 :                         fprintf (dump_file, "Changed conditional jump %d->%d "
    2852              :                                  "to conditional return.\n",
    2853            0 :                                  b->index, BRANCH_EDGE (b)->dest->index);
    2854            0 :                       redirect_edge_succ (BRANCH_EDGE (b),
    2855            0 :                                           EXIT_BLOCK_PTR_FOR_FN (cfun));
    2856            0 :                       BRANCH_EDGE (b)->flags &= ~EDGE_CROSSING;
    2857            0 :                       changed_here = true;
    2858              :                     }
    2859              :                 }
    2860              : 
    2861              :               /* Try to flip a conditional branch that falls through to
    2862              :                  a return so that it becomes a conditional return and a
    2863              :                  new jump to the original branch target.  */
    2864    404209576 :               if (EDGE_COUNT (b->succs) == 2
    2865    211726206 :                   && BRANCH_EDGE (b)->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
    2866    211726206 :                   && any_condjump_p (BB_END (b))
    2867    589435886 :                   && bb_is_just_return (FALLTHRU_EDGE (b)->dest, &ret, &use))
    2868              :                 {
    2869       160864 :                   if (invert_jump (as_a <rtx_jump_insn *> (BB_END (b)),
    2870       160864 :                                    JUMP_LABEL (BB_END (b)), 0))
    2871              :                     {
    2872       160864 :                       basic_block new_ft = BRANCH_EDGE (b)->dest;
    2873       160864 :                       if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)),
    2874       160864 :                                          PATTERN (ret), 0))
    2875              :                         {
    2876            0 :                           if (use)
    2877            0 :                             emit_insn_before (copy_insn (PATTERN (use)),
    2878            0 :                                               BB_END (b));
    2879            0 :                           if (dump_file)
    2880            0 :                             fprintf (dump_file, "Changed conditional jump "
    2881              :                                      "%d->%d to conditional return, adding "
    2882              :                                      "fall-through jump.\n",
    2883            0 :                                      b->index, BRANCH_EDGE (b)->dest->index);
    2884            0 :                           redirect_edge_succ (BRANCH_EDGE (b),
    2885            0 :                                               EXIT_BLOCK_PTR_FOR_FN (cfun));
    2886            0 :                           BRANCH_EDGE (b)->flags &= ~EDGE_CROSSING;
    2887            0 :                           std::swap (BRANCH_EDGE (b)->probability,
    2888            0 :                                      FALLTHRU_EDGE (b)->probability);
    2889            0 :                           update_br_prob_note (b);
    2890            0 :                           basic_block jb = force_nonfallthru (FALLTHRU_EDGE (b));
    2891            0 :                           notice_new_block (jb);
    2892            0 :                           if (!redirect_jump (as_a <rtx_jump_insn *> (BB_END (jb)),
    2893            0 :                                               block_label (new_ft), 0))
    2894            0 :                             gcc_unreachable ();
    2895            0 :                           redirect_edge_succ (single_succ_edge (jb), new_ft);
    2896            0 :                           changed_here = true;
    2897              :                         }
    2898              :                       else
    2899              :                         {
    2900              :                           /* Invert the jump back to what it was.  This should
    2901              :                              never fail.  */
    2902       160864 :                           if (!invert_jump (as_a <rtx_jump_insn *> (BB_END (b)),
    2903       160864 :                                             JUMP_LABEL (BB_END (b)), 0))
    2904            0 :                             gcc_unreachable ();
    2905              :                         }
    2906              :                     }
    2907              :                 }
    2908              : 
    2909              :               /* Simplify branch over branch.  */
    2910    404209576 :               if ((mode & CLEANUP_EXPENSIVE)
    2911    106942964 :                    && !(mode & CLEANUP_CFGLAYOUT)
    2912    438895013 :                    && try_simplify_condjump (b))
    2913              :                 changed_here = true;
    2914              : 
    2915              :               /* If B has a single outgoing edge, but uses a
    2916              :                  non-trivial jump instruction without side-effects, we
    2917              :                  can either delete the jump entirely, or replace it
    2918              :                  with a simple unconditional jump.  */
    2919    404209576 :               if (single_succ_p (b)
    2920    175446617 :                   && single_succ (b) != EXIT_BLOCK_PTR_FOR_FN (cfun)
    2921    145326728 :                   && onlyjump_p (BB_END (b))
    2922     29465852 :                   && !CROSSING_JUMP_P (BB_END (b))
    2923    430691238 :                   && try_redirect_by_replacing_jump (single_succ_edge (b),
    2924              :                                                      single_succ (b),
    2925     28252170 :                                                      (mode & CLEANUP_CFGLAYOUT) != 0))
    2926              :                 {
    2927      4294574 :                   update_forwarder_flag (b);
    2928      4294574 :                   changed_here = true;
    2929              :                 }
    2930              : 
    2931              :               /* Simplify branch to branch.  */
    2932    404209576 :               if (try_forward_edges (mode, b))
    2933              :                 {
    2934      6480440 :                   update_forwarder_flag (b);
    2935      6480440 :                   changed_here = true;
    2936              :                 }
    2937              : 
    2938              :               /* Look for shared code between blocks.  */
    2939    404209576 :               if ((mode & CLEANUP_CROSSJUMP)
    2940    404209576 :                   && try_crossjump_bb (mode, b))
    2941              :                 changed_here = true;
    2942              : 
    2943    404209576 :               if ((mode & CLEANUP_CROSSJUMP)
    2944              :                   /* This can lengthen register lifetimes.  Do it only after
    2945              :                      reload.  */
    2946     29785841 :                   && reload_completed
    2947    433995417 :                   && try_head_merge_bb (b))
    2948              :                 changed_here = true;
    2949              : 
    2950              :               /* Don't get confused by the index shift caused by
    2951              :                  deleting blocks.  */
    2952    404171223 :               if (!changed_here)
    2953    389261677 :                 b = b->next_bb;
    2954              :               else
    2955              :                 changed = true;
    2956              :             }
    2957              : 
    2958     25994196 :           if ((mode & CLEANUP_CROSSJUMP)
    2959     25994196 :               && try_crossjump_bb (mode, EXIT_BLOCK_PTR_FOR_FN (cfun)))
    2960              :             changed = true;
    2961              : 
    2962     25994196 :           if (block_was_dirty)
    2963              :             {
    2964              :               /* This should only be set by head-merging.  */
    2965       196361 :               gcc_assert (mode & CLEANUP_CROSSJUMP);
    2966       196361 :               df_analyze ();
    2967              :             }
    2968              : 
    2969     25994196 :           if (changed)
    2970              :             {
    2971              :               /* Edge forwarding in particular can cause hot blocks previously
    2972              :                  reached by both hot and cold blocks to become dominated only
    2973              :                  by cold blocks. This will cause the verification below to fail,
    2974              :                  and lead to now cold code in the hot section. This is not easy
    2975              :                  to detect and fix during edge forwarding, and in some cases
    2976              :                  is only visible after newly unreachable blocks are deleted,
    2977              :                  which will be done in fixup_partitions.  */
    2978      3884472 :               if ((mode & CLEANUP_NO_PARTITIONING) == 0)
    2979              :                 {
    2980      3746132 :                   fixup_partitions ();
    2981      3746132 :                   checking_verify_flow_info ();
    2982              :                 }
    2983              :             }
    2984              : 
    2985     25994196 :           changed_overall |= changed;
    2986     25994196 :           first_pass = false;
    2987              :         }
    2988              :       while (changed);
    2989              :     }
    2990              : 
    2991    356119487 :   FOR_ALL_BB_FN (b, cfun)
    2992    334009763 :     b->flags &= ~(BB_FORWARDER_BLOCK | BB_NONTHREADABLE_BLOCK);
    2993              : 
    2994     22109724 :   return changed_overall;
    2995              : }
    2996              : 
    2997              : /* Delete all unreachable basic blocks.  */
    2998              : 
    2999              : bool
    3000     28554415 : delete_unreachable_blocks (void)
    3001              : {
    3002     28554415 :   bool changed = false;
    3003     28554415 :   basic_block b, prev_bb;
    3004              : 
    3005     28554415 :   find_unreachable_blocks ();
    3006              : 
    3007              :   /* When we're in GIMPLE mode and there may be debug bind insns, we
    3008              :      should delete blocks in reverse dominator order, so as to get a
    3009              :      chance to substitute all released DEFs into debug bind stmts.  If
    3010              :      we don't have dominators information, walking blocks backward
    3011              :      gets us a better chance of retaining most debug information than
    3012              :      otherwise.  */
    3013     12941905 :   if (MAY_HAVE_DEBUG_BIND_INSNS && current_ir_type () == IR_GIMPLE
    3014     28826075 :       && dom_info_available_p (CDI_DOMINATORS))
    3015              :     {
    3016            0 :       for (b = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
    3017            0 :            b != ENTRY_BLOCK_PTR_FOR_FN (cfun); b = prev_bb)
    3018              :         {
    3019            0 :           prev_bb = b->prev_bb;
    3020              : 
    3021            0 :           if (!(b->flags & BB_REACHABLE))
    3022              :             {
    3023              :               /* Speed up the removal of blocks that don't dominate
    3024              :                  others.  Walking backwards, this should be the common
    3025              :                  case.  */
    3026            0 :               if (!first_dom_son (CDI_DOMINATORS, b))
    3027            0 :                 delete_basic_block (b);
    3028              :               else
    3029              :                 {
    3030            0 :                   auto_vec<basic_block> h
    3031            0 :                     = get_all_dominated_blocks (CDI_DOMINATORS, b);
    3032              : 
    3033            0 :                   while (h.length ())
    3034              :                     {
    3035            0 :                       b = h.pop ();
    3036              : 
    3037            0 :                       prev_bb = b->prev_bb;
    3038              : 
    3039            0 :                       gcc_assert (!(b->flags & BB_REACHABLE));
    3040              : 
    3041            0 :                       delete_basic_block (b);
    3042              :                     }
    3043            0 :                 }
    3044              : 
    3045              :               changed = true;
    3046              :             }
    3047              :         }
    3048              :     }
    3049              :   else
    3050              :     {
    3051     28554415 :       for (b = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
    3052    423315774 :            b != ENTRY_BLOCK_PTR_FOR_FN (cfun); b = prev_bb)
    3053              :         {
    3054    394761359 :           prev_bb = b->prev_bb;
    3055              : 
    3056    394761359 :           if (!(b->flags & BB_REACHABLE))
    3057              :             {
    3058      1698264 :               delete_basic_block (b);
    3059      1698264 :               changed = true;
    3060              :             }
    3061              :         }
    3062              :     }
    3063              : 
    3064     28554415 :   if (changed)
    3065       462864 :     tidy_fallthru_edges ();
    3066     28554415 :   return changed;
    3067              : }
    3068              : 
    3069              : /* Delete any jump tables never referenced.  We can't delete them at the
    3070              :    time of removing tablejump insn as they are referenced by the preceding
    3071              :    insns computing the destination, so we delay deleting and garbagecollect
    3072              :    them once life information is computed.  */
    3073              : void
    3074      9269945 : delete_dead_jumptables (void)
    3075              : {
    3076      9269945 :   basic_block bb;
    3077              : 
    3078              :   /* A dead jump table does not belong to any basic block.  Scan insns
    3079              :      between two adjacent basic blocks.  */
    3080    103041080 :   FOR_EACH_BB_FN (bb, cfun)
    3081              :     {
    3082     93771135 :       rtx_insn *insn, *next;
    3083              : 
    3084     93771135 :       for (insn = NEXT_INSN (BB_END (bb));
    3085    171559898 :            insn && !NOTE_INSN_BASIC_BLOCK_P (insn);
    3086              :            insn = next)
    3087              :         {
    3088     77788763 :           next = NEXT_INSN (insn);
    3089     77788763 :           if (LABEL_P (insn)
    3090     44067383 :               && LABEL_NUSES (insn) == LABEL_PRESERVE_P (insn)
    3091     79728110 :               && JUMP_TABLE_DATA_P (next))
    3092              :             {
    3093            0 :               rtx_insn *label = insn, *jump = next;
    3094              : 
    3095            0 :               if (dump_file)
    3096            0 :                 fprintf (dump_file, "Dead jumptable %i removed\n",
    3097            0 :                          INSN_UID (insn));
    3098              : 
    3099            0 :               next = NEXT_INSN (next);
    3100            0 :               delete_insn (jump);
    3101            0 :               delete_insn (label);
    3102              :             }
    3103              :         }
    3104              :     }
    3105      9269945 : }
    3106              : 
    3107              : 
    3108              : /* Tidy the CFG by deleting unreachable code and whatnot.  */
    3109              : 
    3110              : bool
    3111     19926754 : cleanup_cfg (int mode)
    3112              : {
    3113     19926754 :   bool changed = false;
    3114              : 
    3115              :   /* Set the cfglayout mode flag here.  We could update all the callers
    3116              :      but that is just inconvenient, especially given that we eventually
    3117              :      want to have cfglayout mode as the default.  */
    3118     19926754 :   if (current_ir_type () == IR_RTL_CFGLAYOUT)
    3119     13219128 :     mode |= CLEANUP_CFGLAYOUT;
    3120              : 
    3121     19926754 :   timevar_push (TV_CLEANUP_CFG);
    3122     19926754 :   if (delete_unreachable_blocks ())
    3123              :     {
    3124       157190 :       changed = true;
    3125              :       /* We've possibly created trivially dead code.  Cleanup it right
    3126              :          now to introduce more opportunities for try_optimize_cfg.  */
    3127       157190 :       if (!(mode & (CLEANUP_NO_INSN_DEL))
    3128        41899 :           && !reload_completed)
    3129        41819 :         delete_trivially_dead_insns (get_insns (), max_reg_num ());
    3130              :     }
    3131              : 
    3132     19926754 :   compact_blocks ();
    3133              : 
    3134              :   /* To tail-merge blocks ending in the same noreturn function (e.g.
    3135              :      a call to abort) we have to insert fake edges to exit.  Do this
    3136              :      here once.  The fake edges do not interfere with any other CFG
    3137              :      cleanups.  */
    3138     19926754 :   if (mode & CLEANUP_CROSSJUMP)
    3139       976484 :     add_noreturn_fake_exit_edges ();
    3140              : 
    3141     19926754 :   if (!dbg_cnt (cfg_cleanup))
    3142              :     return changed;
    3143              : 
    3144     22109724 :   while (try_optimize_cfg (mode))
    3145              :     {
    3146      3795426 :       delete_unreachable_blocks (), changed = true;
    3147      3795426 :       if (!(mode & CLEANUP_NO_INSN_DEL))
    3148              :         {
    3149              :           /* Try to remove some trivially dead insns when doing an expensive
    3150              :              cleanup.  But delete_trivially_dead_insns doesn't work after
    3151              :              reload (it only handles pseudos) and run_fast_dce is too costly
    3152              :              to run in every iteration.
    3153              : 
    3154              :              For effective cross jumping, we really want to run a fast DCE to
    3155              :              clean up any dead conditions, or they get in the way of performing
    3156              :              useful tail merges.
    3157              : 
    3158              :              Other transformations in cleanup_cfg are not so sensitive to dead
    3159              :              code, so delete_trivially_dead_insns or even doing nothing at all
    3160              :              is good enough.  */
    3161       640226 :           if ((mode & CLEANUP_EXPENSIVE) && !reload_completed
    3162      2245394 :               && !delete_trivially_dead_insns (get_insns (), max_reg_num ()))
    3163              :             break;
    3164      2182970 :           if ((mode & CLEANUP_CROSSJUMP) && crossjumps_occurred)
    3165              :             {
    3166        79764 :               run_fast_dce ();
    3167        79764 :               mode &= ~CLEANUP_FORCE_FAST_DCE;
    3168              :             }
    3169              :         }
    3170              :       else
    3171              :         break;
    3172              :     }
    3173              : 
    3174     19926754 :   if (mode & CLEANUP_CROSSJUMP)
    3175       976484 :     remove_fake_exit_edges ();
    3176              : 
    3177     19926754 :   if (mode & CLEANUP_FORCE_FAST_DCE)
    3178       118545 :     run_fast_dce ();
    3179              : 
    3180              :   /* Don't call delete_dead_jumptables in cfglayout mode, because
    3181              :      that function assumes that jump tables are in the insns stream.
    3182              :      But we also don't _have_ to delete dead jumptables in cfglayout
    3183              :      mode because we shouldn't even be looking at things that are
    3184              :      not in a basic block.  Dead jumptables are cleaned up when
    3185              :      going out of cfglayout mode.  */
    3186     19926754 :   if (!(mode & CLEANUP_CFGLAYOUT))
    3187      6707626 :     delete_dead_jumptables ();
    3188              : 
    3189              :   /* ???  We probably do this way too often.  */
    3190     19926754 :   if (current_loops
    3191      9286881 :       && (changed
    3192      6857413 :           || (mode & CLEANUP_CFG_CHANGED)))
    3193              :     {
    3194      2521715 :       timevar_push (TV_REPAIR_LOOPS);
    3195              :       /* The above doesn't preserve dominance info if available.  */
    3196      2521715 :       gcc_assert (!dom_info_available_p (CDI_DOMINATORS));
    3197      2521715 :       calculate_dominance_info (CDI_DOMINATORS);
    3198      2521715 :       fix_loop_structure (NULL);
    3199      2521715 :       free_dominance_info (CDI_DOMINATORS);
    3200      2521715 :       timevar_pop (TV_REPAIR_LOOPS);
    3201              :     }
    3202              : 
    3203     19926754 :   timevar_pop (TV_CLEANUP_CFG);
    3204              : 
    3205     19926754 :   return changed;
    3206              : }
    3207              : 
    3208              : namespace {
    3209              : 
    3210              : const pass_data pass_data_jump =
    3211              : {
    3212              :   RTL_PASS, /* type */
    3213              :   "jump", /* name */
    3214              :   OPTGROUP_NONE, /* optinfo_flags */
    3215              :   TV_JUMP, /* tv_id */
    3216              :   0, /* properties_required */
    3217              :   0, /* properties_provided */
    3218              :   0, /* properties_destroyed */
    3219              :   0, /* todo_flags_start */
    3220              :   0, /* todo_flags_finish */
    3221              : };
    3222              : 
    3223              : class pass_jump : public rtl_opt_pass
    3224              : {
    3225              : public:
    3226       292371 :   pass_jump (gcc::context *ctxt)
    3227       584742 :     : rtl_opt_pass (pass_data_jump, ctxt)
    3228              :   {}
    3229              : 
    3230              :   /* opt_pass methods: */
    3231              :   unsigned int execute (function *) final override;
    3232              : 
    3233              : }; // class pass_jump
    3234              : 
    3235              : unsigned int
    3236      1504947 : pass_jump::execute (function *)
    3237              : {
    3238      1504947 :   delete_trivially_dead_insns (get_insns (), max_reg_num ());
    3239      1504947 :   if (dump_file)
    3240           84 :     dump_flow_info (dump_file, dump_flags);
    3241      3009894 :   cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0)
    3242      1056939 :                | (flag_thread_jumps && flag_expensive_optimizations
    3243      1504947 :                   ? CLEANUP_THREADING : 0));
    3244      1504947 :   return 0;
    3245              : }
    3246              : 
    3247              : } // anon namespace
    3248              : 
    3249              : rtl_opt_pass *
    3250       292371 : make_pass_jump (gcc::context *ctxt)
    3251              : {
    3252       292371 :   return new pass_jump (ctxt);
    3253              : }
    3254              : 
    3255              : namespace {
    3256              : 
    3257              : const pass_data pass_data_jump_after_combine =
    3258              : {
    3259              :   RTL_PASS, /* type */
    3260              :   "jump_after_combine", /* name */
    3261              :   OPTGROUP_NONE, /* optinfo_flags */
    3262              :   TV_JUMP, /* tv_id */
    3263              :   0, /* properties_required */
    3264              :   0, /* properties_provided */
    3265              :   0, /* properties_destroyed */
    3266              :   0, /* todo_flags_start */
    3267              :   0, /* todo_flags_finish */
    3268              : };
    3269              : 
    3270              : class pass_jump_after_combine : public rtl_opt_pass
    3271              : {
    3272              : public:
    3273       292371 :   pass_jump_after_combine (gcc::context *ctxt)
    3274       584742 :     : rtl_opt_pass (pass_data_jump_after_combine, ctxt)
    3275              :   {}
    3276              : 
    3277              :   /* opt_pass methods: */
    3278      1504958 :   bool gate (function *) final override
    3279              :   {
    3280      1504958 :     return flag_thread_jumps && flag_expensive_optimizations;
    3281              :   }
    3282              :   unsigned int execute (function *) final override;
    3283              : 
    3284              : }; // class pass_jump_after_combine
    3285              : 
    3286              : unsigned int
    3287       976339 : pass_jump_after_combine::execute (function *)
    3288              : {
    3289              :   /* Jump threading does not keep dominators up-to-date.  */
    3290       976339 :   free_dominance_info (CDI_DOMINATORS);
    3291       976339 :   cleanup_cfg (CLEANUP_THREADING);
    3292       976339 :   return 0;
    3293              : }
    3294              : 
    3295              : } // anon namespace
    3296              : 
    3297              : rtl_opt_pass *
    3298       292371 : make_pass_jump_after_combine (gcc::context *ctxt)
    3299              : {
    3300       292371 :   return new pass_jump_after_combine (ctxt);
    3301              : }
    3302              : 
    3303              : namespace {
    3304              : 
    3305              : const pass_data pass_data_jump2 =
    3306              : {
    3307              :   RTL_PASS, /* type */
    3308              :   "jump2", /* name */
    3309              :   OPTGROUP_NONE, /* optinfo_flags */
    3310              :   TV_JUMP, /* tv_id */
    3311              :   0, /* properties_required */
    3312              :   0, /* properties_provided */
    3313              :   0, /* properties_destroyed */
    3314              :   0, /* todo_flags_start */
    3315              :   0, /* todo_flags_finish */
    3316              : };
    3317              : 
    3318              : class pass_jump2 : public rtl_opt_pass
    3319              : {
    3320              : public:
    3321       292371 :   pass_jump2 (gcc::context *ctxt)
    3322       584742 :     : rtl_opt_pass (pass_data_jump2, ctxt)
    3323              :   {}
    3324              : 
    3325              :   /* opt_pass methods: */
    3326      1504951 :   unsigned int execute (function *) final override
    3327              :     {
    3328      2033418 :       cleanup_cfg (flag_crossjumping ? CLEANUP_CROSSJUMP : 0);
    3329      1504951 :       return 0;
    3330              :     }
    3331              : 
    3332              : }; // class pass_jump2
    3333              : 
    3334              : } // anon namespace
    3335              : 
    3336              : rtl_opt_pass *
    3337       292371 : make_pass_jump2 (gcc::context *ctxt)
    3338              : {
    3339       292371 :   return new pass_jump2 (ctxt);
    3340              : }
        

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.