LCOV - code coverage report
Current view: top level - gcc - cfgcleanup.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.1 % 1429 1331
Test Date: 2026-10-17 16:30:31 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        20877 : notice_new_block (basic_block bb)
      90              : {
      91        20877 :   if (!bb)
      92              :     return;
      93              : 
      94        14986 :   if (forwarder_block_p (bb))
      95        14986 :     bb->flags |= BB_FORWARDER_BLOCK;
      96              : }
      97              : 
      98              : /* Recompute forwarder flag after block has been modified.  */
      99              : 
     100              : static void
     101    321415162 : update_forwarder_flag (basic_block bb)
     102              : {
     103    321415162 :   if (forwarder_block_p (bb))
     104     16885431 :     bb->flags |= BB_FORWARDER_BLOCK;
     105              :   else
     106    304529731 :     bb->flags &= ~BB_FORWARDER_BLOCK;
     107    321415162 : }
     108              : 
     109              : /* Simplify a conditional jump around an unconditional jump.
     110              :    Return true if something changed.  */
     111              : 
     112              : static bool
     113     35378687 : try_simplify_condjump (basic_block cbranch_block)
     114              : {
     115     35378687 :   basic_block jump_block, jump_dest_block, cbranch_dest_block;
     116     35378687 :   edge cbranch_jump_edge, cbranch_fallthru_edge;
     117     35378687 :   rtx_insn *cbranch_insn;
     118              : 
     119              :   /* Verify that there are exactly two successors.  */
     120     35378687 :   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     17773906 :   cbranch_insn = BB_END (cbranch_block);
     126     17773906 :   if (!any_condjump_p (cbranch_insn))
     127              :     return false;
     128              : 
     129     15466911 :   cbranch_fallthru_edge = FALLTHRU_EDGE (cbranch_block);
     130     15466911 :   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     15466911 :   jump_block = cbranch_fallthru_edge->dest;
     136     15466911 :   if (!single_pred_p (jump_block)
     137     13737563 :       || jump_block->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
     138     29038651 :       || !FORWARDER_BLOCK_P (jump_block))
     139              :     return false;
     140      1726018 :   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      1726018 :   if (BB_PARTITION (jump_block) != BB_PARTITION (jump_dest_block)
     153      1686739 :       || (cbranch_jump_edge->flags & EDGE_CROSSING))
     154              :     return false;
     155              : 
     156              :   /* The conditional branch must target the block after the
     157              :      unconditional branch.  */
     158      1440104 :   cbranch_dest_block = cbranch_jump_edge->dest;
     159              : 
     160      1440104 :   if (cbranch_dest_block == EXIT_BLOCK_PTR_FOR_FN (cfun)
     161      1440104 :       || jump_dest_block == EXIT_BLOCK_PTR_FOR_FN (cfun)
     162      2879392 :       || !can_fallthru (jump_block, cbranch_dest_block))
     163              :     return false;
     164              : 
     165              :   /* Invert the conditional branch.  */
     166         7527 :   if (!invert_jump (as_a <rtx_jump_insn *> (cbranch_insn),
     167         7527 :                     block_label (jump_dest_block), 0))
     168              :     return false;
     169              : 
     170         7527 :   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         7527 :   cbranch_jump_edge = redirect_edge_succ_nodup (cbranch_jump_edge,
     178              :                                                 cbranch_dest_block);
     179         7527 :   cbranch_fallthru_edge = redirect_edge_succ_nodup (cbranch_fallthru_edge,
     180              :                                                     jump_dest_block);
     181         7527 :   cbranch_jump_edge->flags |= EDGE_FALLTHRU;
     182         7527 :   cbranch_fallthru_edge->flags &= ~EDGE_FALLTHRU;
     183         7527 :   update_br_prob_note (cbranch_block);
     184              : 
     185              :   /* Delete the block with the unconditional jump, and clean up the mess.  */
     186         7527 :   delete_basic_block (jump_block);
     187         7527 :   tidy_fallthru_edge (cbranch_jump_edge);
     188         7527 :   update_forwarder_flag (cbranch_block);
     189              : 
     190         7527 :   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     34607905 : mark_effect (rtx exp, regset nonequal)
     198              : {
     199     34607905 :   rtx dest;
     200     34607905 :   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      2535260 :     case CLOBBER:
     205      2535260 :       dest = XEXP (exp, 0);
     206      2535260 :       if (REG_P (dest))
     207      2501414 :         bitmap_clear_range (nonequal, REGNO (dest), REG_NREGS (dest));
     208              :       return false;
     209              : 
     210     11346430 :     case SET:
     211     11346430 :       if (cselib_redundant_set_p (exp))
     212              :         return false;
     213     11154981 :       dest = SET_DEST (exp);
     214     11154981 :       if (dest == pc_rtx)
     215              :         return false;
     216     11147140 :       if (!REG_P (dest))
     217              :         return true;
     218     10589643 :       bitmap_set_range (nonequal, REGNO (dest), REG_NREGS (dest));
     219     10589643 :       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      3661804 : mentions_nonequal_regs (const_rtx x, regset nonequal)
     229              : {
     230      3661804 :   subrtx_iterator::array_type array;
     231      7340430 :   FOR_EACH_SUBRTX (iter, array, x, NONCONST)
     232              :     {
     233      7332589 :       const_rtx x = *iter;
     234      7332589 :       if (REG_P (x))
     235              :         {
     236      3662089 :           unsigned int end_regno = END_REGNO (x);
     237      3670215 :           for (unsigned int regno = REGNO (x); regno < end_regno; ++regno)
     238      3662089 :             if (REGNO_REG_SET_P (nonequal, regno))
     239      3653963 :               return true;
     240              :         }
     241              :     }
     242         7841 :   return false;
     243      3661804 : }
     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     28947251 : thread_jump (edge e, basic_block b)
     251              : {
     252     28947251 :   rtx set1, set2, cond1, cond2;
     253     28947251 :   rtx_insn *insn;
     254     28947251 :   enum rtx_code code1, code2, reversed_code2;
     255     28947251 :   bool reverse1 = false;
     256     28947251 :   unsigned i;
     257     28947251 :   regset nonequal;
     258     28947251 :   bool failed = false;
     259              : 
     260              :   /* Jump threading may cause fixup_partitions to introduce new crossing edges,
     261              :      which is not allowed after reload.  */
     262     28947251 :   gcc_checking_assert (!reload_completed || !crtl->has_bb_partition);
     263              : 
     264     28947251 :   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     24892569 :   if (EDGE_COUNT (e->src->succs) != 2)
     270              :     return NULL;
     271     17493196 :   if (EDGE_COUNT (b->succs) != 2)
     272              :     {
     273      7712227 :       b->flags |= BB_NONTHREADABLE_BLOCK;
     274      7712227 :       return NULL;
     275              :     }
     276              : 
     277              :   /* Second branch must end with onlyjump, as we will eliminate the jump.  */
     278      9780969 :   if (!any_condjump_p (BB_END (e->src)))
     279              :     return NULL;
     280              : 
     281      8873587 :   if (!any_condjump_p (BB_END (b)) || !onlyjump_p (BB_END (b)))
     282              :     {
     283       672076 :       b->flags |= BB_NONTHREADABLE_BLOCK;
     284       672076 :       return NULL;
     285              :     }
     286              : 
     287      8201511 :   set1 = pc_set (BB_END (e->src));
     288      8201511 :   set2 = pc_set (BB_END (b));
     289      8201511 :   if (((e->flags & EDGE_FALLTHRU) != 0)
     290      8201511 :       != (XEXP (SET_SRC (set1), 1) == pc_rtx))
     291      4059149 :     reverse1 = true;
     292              : 
     293      8201511 :   cond1 = XEXP (SET_SRC (set1), 0);
     294      8201511 :   cond2 = XEXP (SET_SRC (set2), 0);
     295      8201511 :   if (reverse1)
     296      4059149 :     code1 = reversed_comparison_code (cond1, BB_END (e->src));
     297              :   else
     298      4142362 :     code1 = GET_CODE (cond1);
     299              : 
     300      8201511 :   code2 = GET_CODE (cond2);
     301      8201511 :   reversed_code2 = reversed_comparison_code (cond2, BB_END (b));
     302              : 
     303      8201511 :   if (!comparison_dominates_p (code1, code2)
     304      8201511 :       && !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      6597141 :   if (!rtx_equal_p (XEXP (cond1, 0), XEXP (cond2, 0))
     312      6597141 :       || !rtx_equal_p (XEXP (cond1, 1), XEXP (cond2, 1)))
     313              :     return NULL;
     314              : 
     315              :   /* Punt if BB_END (e->src) is doloop-like conditional jump that modifies
     316              :      the registers used in cond1.  */
     317      5662799 :   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     65914811 :   for (insn = NEXT_INSN (BB_HEAD (b)); insn != NEXT_INSN (BB_END (b));
     323     54589213 :        insn = NEXT_INSN (insn))
     324     56032711 :     if (INSN_P (insn) && side_effects_p (PATTERN (insn)))
     325              :       {
     326      1443498 :         b->flags |= BB_NONTHREADABLE_BLOCK;
     327      1443498 :         return NULL;
     328              :       }
     329              : 
     330      4219301 :   cselib_init (0);
     331              : 
     332              :   /* First process all values computed in the source basic block.  */
     333     60988372 :   for (insn = NEXT_INSN (BB_HEAD (e->src));
     334     60988372 :        insn != NEXT_INSN (BB_END (e->src));
     335     56769071 :        insn = NEXT_INSN (insn))
     336     56769071 :     if (INSN_P (insn))
     337     52996318 :       cselib_process_insn (insn);
     338              : 
     339      4219301 :   nonequal = BITMAP_ALLOC (NULL);
     340      4219301 :   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     39315469 :   for (insn = NEXT_INSN (BB_HEAD (b));
     347     39315469 :        insn != NEXT_INSN (BB_END (b)) && !failed;
     348     35096168 :        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     38750131 :       if (insn == BB_END (b)
     354     38750131 :           && mentions_nonequal_regs (cond2, nonequal))
     355      3653963 :         goto failed_exit;
     356              : 
     357     35096168 :       if (INSN_P (insn))
     358              :         {
     359     31972196 :           rtx pat = PATTERN (insn);
     360              : 
     361     31972196 :           if (GET_CODE (pat) == PARALLEL)
     362              :             {
     363      7725701 :               for (i = 0; i < (unsigned)XVECLEN (pat, 0); i++)
     364      5180705 :                 failed |= mark_effect (XVECEXP (pat, 0, i), nonequal);
     365              :             }
     366              :           else
     367     29427200 :             failed |= mark_effect (pat, nonequal);
     368              :         }
     369              : 
     370     35096168 :       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       565338 :   if (failed)
     376              :     {
     377       557497 :       b->flags |= BB_NONTHREADABLE_BLOCK;
     378       557497 :       goto failed_exit;
     379              :     }
     380              : 
     381         7841 :   if (!REG_SET_EMPTY_P (nonequal))
     382          539 :     goto failed_exit;
     383              : 
     384         7302 :   BITMAP_FREE (nonequal);
     385         7302 :   cselib_finish ();
     386         7302 :   if ((comparison_dominates_p (code1, code2) != 0)
     387         7302 :       != (XEXP (SET_SRC (set2), 1) == pc_rtx))
     388         5144 :     return BRANCH_EDGE (b);
     389              :   else
     390         2158 :     return FALLTHRU_EDGE (b);
     391              : 
     392      4211999 : failed_exit:
     393      4211999 :   BITMAP_FREE (nonequal);
     394      4211999 :   cselib_finish ();
     395      4211999 :   return NULL;
     396              : }
     397              : 
     398              : /* Attempt to forward edges leaving basic block B.
     399              :    Return true if successful.  */
     400              : 
     401              : static bool
     402    411192794 : try_forward_edges (int mode, basic_block b)
     403              : {
     404    411192794 :   bool changed = false;
     405    411192794 :   edge_iterator ei;
     406    411192794 :   edge e, *threaded_edges = NULL;
     407              : 
     408   1030858015 :   for (ei = ei_start (b->succs); (e = ei_safe_edge (ei)); )
     409              :     {
     410    619665221 :       basic_block target, first;
     411    619665221 :       location_t goto_locus;
     412    619665221 :       int counter;
     413    619665221 :       bool threaded = false;
     414    619665221 :       int nthreaded_edges = 0;
     415    619665221 :       bool may_thread = first_pass || (b->flags & BB_MODIFIED) != 0;
     416    619665221 :       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    619665221 :       if (e->flags & EDGE_COMPLEX)
     424              :         {
     425     36219621 :           ei_next (&ei);
     426     36219621 :           continue;
     427              :         }
     428              : 
     429    583445600 :       target = first = e->dest;
     430    583445600 :       counter = NUM_FIXED_BLOCKS;
     431    583445600 :       goto_locus = e->goto_locus;
     432              : 
     433    613495692 :       while (counter < n_basic_blocks_for_fn (cfun))
     434              :         {
     435    613094235 :           basic_block new_target = NULL;
     436    613094235 :           may_thread |= (target->flags & BB_MODIFIED) != 0;
     437              : 
     438    613094235 :           if (FORWARDER_BLOCK_P (target)
     439    652712260 :               && single_succ (target) != EXIT_BLOCK_PTR_FOR_FN (cfun))
     440              :             {
     441              :               /* Bypass trivial infinite loops.  */
     442     30232800 :               new_target = single_succ (target);
     443     30232800 :               if (target == new_target)
     444              :                 counter = n_basic_blocks_for_fn (cfun);
     445     29970749 :               else if (!optimize)
     446              :                 {
     447              :                   /* When not optimizing, ensure that edges or forwarder
     448              :                      blocks with different locus are not optimized out.  */
     449      1189972 :                   location_t new_locus = single_succ_edge (target)->goto_locus;
     450      1189972 :                   location_t locus = goto_locus;
     451              : 
     452      1189972 :                   if (LOCATION_LOCUS (new_locus) != UNKNOWN_LOCATION
     453       473766 :                       && LOCATION_LOCUS (locus) != UNKNOWN_LOCATION
     454      1500954 :                       && new_locus != locus)
     455              :                     new_target = NULL;
     456              :                   else
     457              :                     {
     458      1009776 :                       if (LOCATION_LOCUS (new_locus) != UNKNOWN_LOCATION)
     459       293570 :                         locus = new_locus;
     460              : 
     461      1009776 :                       rtx_insn *last = BB_END (target);
     462      1009776 :                       if (DEBUG_INSN_P (last))
     463            6 :                         last = prev_nondebug_insn (last);
     464      1009776 :                       if (last && INSN_P (last))
     465       501609 :                         new_locus = INSN_LOCATION (last);
     466              :                       else
     467              :                         new_locus = UNKNOWN_LOCATION;
     468              : 
     469       501609 :                       if (LOCATION_LOCUS (new_locus) != UNKNOWN_LOCATION
     470       484456 :                           && LOCATION_LOCUS (locus) != UNKNOWN_LOCATION
     471      1380093 :                           && new_locus != locus)
     472              :                         new_target = NULL;
     473              :                       else
     474              :                         {
     475      1001301 :                           if (LOCATION_LOCUS (new_locus) != UNKNOWN_LOCATION)
     476       475981 :                             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    582861435 :           else if ((mode & CLEANUP_THREADING) && may_thread)
     487              :             {
     488     28947251 :               edge t = thread_jump (e, target);
     489     28947251 :               if (t)
     490              :                 {
     491         7302 :                   if (!threaded_edges)
     492         7228 :                     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          221 :                       for (i = 0; i < nthreaded_edges; ++i)
     501          166 :                         if (threaded_edges[i] == t)
     502              :                           break;
     503           74 :                       if (i < nthreaded_edges)
     504              :                         {
     505           19 :                           counter = n_basic_blocks_for_fn (cfun);
     506           19 :                           break;
     507              :                         }
     508              :                     }
     509              : 
     510              :                   /* Detect an infinite loop across the start block.  */
     511         7283 :                   if (t->dest == b)
     512              :                     break;
     513              : 
     514         5963 :                   gcc_assert (nthreaded_edges
     515              :                               < (n_basic_blocks_for_fn (cfun)
     516              :                                  - NUM_FIXED_BLOCKS));
     517         5963 :                   threaded_edges[nthreaded_edges++] = t;
     518              : 
     519         5963 :                   new_target = t->dest;
     520         5963 :                   new_target_threaded = true;
     521              :                 }
     522              :             }
     523              : 
     524     30050092 :           if (!new_target)
     525              :             break;
     526              : 
     527     30050092 :           counter++;
     528              :           /* Do not turn non-crossing jump to crossing.  Depending on target
     529              :              it may require different instruction pattern.  */
     530     30050092 :           if ((e->flags & EDGE_CROSSING)
     531     30016091 :               || BB_PARTITION (first) == BB_PARTITION (new_target))
     532              :             {
     533     15458002 :               target = new_target;
     534     15458002 :               threaded |= new_target_threaded;
     535              :             }
     536              :         }
     537              : 
     538    583445600 :       if (counter >= n_basic_blocks_for_fn (cfun))
     539              :         {
     540       401476 :           if (dump_file)
     541            4 :             fprintf (dump_file, "Infinite loop in BB %i.\n",
     542              :                      target->index);
     543              :         }
     544    583044124 :       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     14322796 :           profile_count edge_count = e->count ();
     550     14322796 :           int n = 0;
     551              : 
     552     14322796 :           e->goto_locus = goto_locus;
     553              : 
     554              :           /* Don't force if target is exit block.  */
     555     14322796 :           if (threaded && target != EXIT_BLOCK_PTR_FOR_FN (cfun))
     556              :             {
     557         5891 :               notice_new_block (redirect_edge_and_branch_force (e, target));
     558         5891 :               if (dump_file)
     559            0 :                 fprintf (dump_file, "Conditionals threaded.\n");
     560              :             }
     561     14316905 :           else if (!redirect_edge_and_branch (e, target))
     562              :             {
     563      7589812 :               if (dump_file)
     564          183 :                 fprintf (dump_file,
     565              :                          "Forwarding edge %i->%i to %i failed.\n",
     566          183 :                          b->index, e->dest->index, target->index);
     567      7589812 :               ei_next (&ei);
     568      7589812 :               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      6860928 :           do
     575              :             {
     576      6860928 :               edge t;
     577              : 
     578      6860928 :               if (!single_succ_p (first))
     579              :                 {
     580         5944 :                   gcc_assert (n < nthreaded_edges);
     581         5944 :                   t = threaded_edges [n++];
     582         5944 :                   gcc_assert (t->src == first);
     583         5944 :                   update_bb_profile_for_threading (first, edge_count, t);
     584         5944 :                   update_br_prob_note (first);
     585              :                 }
     586              :               else
     587              :                 {
     588      6854984 :                   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      6854984 :                   if (n < nthreaded_edges
     594            0 :                       && first == threaded_edges [n]->src)
     595            0 :                     n++;
     596      6854984 :                   t = single_succ_edge (first);
     597              :                 }
     598              : 
     599      6860928 :               first = t->dest;
     600              :             }
     601      6860928 :           while (first != target);
     602              : 
     603      6732984 :           changed = true;
     604      6732984 :           continue;
     605      6732984 :         }
     606    569122804 :       ei_next (&ei);
     607              :     }
     608              : 
     609    411192794 :   free (threaded_edges);
     610    411192794 :   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        21562 : merge_blocks_move_predecessor_nojumps (basic_block a, basic_block b)
     620              : {
     621        21562 :   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        21562 :   if (BB_PARTITION (a) != BB_PARTITION (b))
     634              :     return;
     635              : 
     636        21562 :   barrier = next_nonnote_insn (BB_END (a));
     637        21562 :   gcc_assert (BARRIER_P (barrier));
     638        21562 :   delete_insn (barrier);
     639              : 
     640              :   /* Scramble the insn chain.  */
     641        21562 :   if (BB_END (a) != PREV_INSN (BB_HEAD (b)))
     642        21529 :     reorder_insns_nobb (BB_HEAD (a), BB_END (a), PREV_INSN (BB_HEAD (b)));
     643        21562 :   df_set_bb_dirty (a);
     644              : 
     645        21562 :   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        21562 :   unlink_block (a);
     652        21562 :   link_block (a, b->prev_bb);
     653              : 
     654              :   /* Now blocks A and B are contiguous.  Merge them.  */
     655        21562 :   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        30867 : merge_blocks_move_successor_nojumps (basic_block a, basic_block b)
     664              : {
     665        30867 :   rtx_insn *barrier, *real_b_end;
     666        30867 :   rtx_insn *label;
     667        30867 :   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        30867 :   if (BB_PARTITION (a) != BB_PARTITION (b))
     680            0 :     return;
     681              : 
     682        30867 :   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        30867 :   if (tablejump_p (BB_END (b), &label, &table)
     687        30867 :       && 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        30867 :   barrier = NEXT_INSN (BB_END (b));
     694        30867 :   if (barrier && BARRIER_P (barrier))
     695        30867 :     delete_insn (barrier);
     696              : 
     697              : 
     698              :   /* Scramble the insn chain.  */
     699        30867 :   reorder_insns_nobb (BB_HEAD (b), BB_END (b), BB_END (a));
     700              : 
     701              :   /* Restore the real end of b.  */
     702        30867 :   BB_END (b) = real_b_end;
     703              : 
     704        30867 :   if (dump_file)
     705           22 :     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        30867 :   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      6986668 : merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
     726              : {
     727      6986668 :   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      6986668 :   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      6593037 :   if (e->flags & EDGE_FALLTHRU)
     744              :     {
     745      3846862 :       int b_index = b->index, c_index = c->index;
     746              : 
     747              :       /* Protect the loop latches.  */
     748      3846862 :       if (current_loops && c->loop_father->latch == c)
     749              :         return NULL;
     750              : 
     751      3802096 :       merge_blocks (b, c);
     752      3802096 :       update_forwarder_flag (b);
     753              : 
     754      3802096 :       if (dump_file)
     755          910 :         fprintf (dump_file, "Merged %d and %d without moving.\n",
     756              :                  b_index, c_index);
     757              : 
     758      3802096 :       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      2746175 :   else if (mode & CLEANUP_EXPENSIVE)
     764              :     {
     765       918587 :       edge tmp_edge, b_fallthru_edge;
     766       918587 :       bool c_has_outgoing_fallthru;
     767       918587 :       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       918587 :       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        54575 :       tmp_edge = find_fallthru_edge (c->succs);
     781        54575 :       c_has_outgoing_fallthru = (tmp_edge != NULL);
     782              : 
     783        54575 :       tmp_edge = find_fallthru_edge (b->preds);
     784        54575 :       b_has_incoming_fallthru = (tmp_edge != NULL);
     785        54575 :       b_fallthru_edge = tmp_edge;
     786        54575 :       next = b->prev_bb;
     787        54575 :       if (next == c)
     788           63 :         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        54575 :       if (! c_has_outgoing_fallthru)
     794              :         {
     795        30867 :           merge_blocks_move_successor_nojumps (b, c);
     796        30867 :           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        23708 :       if (b_has_incoming_fallthru)
     805              :         {
     806        21621 :           basic_block bb;
     807              : 
     808        21621 :           if (b_fallthru_edge->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
     809              :             return NULL;
     810        19475 :           bb = force_nonfallthru (b_fallthru_edge);
     811        19475 :           if (bb)
     812        14986 :             notice_new_block (bb);
     813              :         }
     814              : 
     815        21562 :       merge_blocks_move_predecessor_nojumps (b, c);
     816        21562 :       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    149552785 : merge_memattrs (rtx x, rtx y)
     828              : {
     829    149552785 :   int i;
     830    149552785 :   int j;
     831    149552785 :   enum rtx_code code;
     832    149552785 :   const char *fmt;
     833              : 
     834    149552785 :   if (x == y)
     835              :     return;
     836    111571284 :   if (x == 0 || y == 0)
     837              :     return;
     838              : 
     839    111532817 :   code = GET_CODE (x);
     840              : 
     841    111532817 :   if (code != GET_CODE (y))
     842              :     return;
     843              : 
     844    111532805 :   if (GET_MODE (x) != GET_MODE (y))
     845              :     return;
     846              : 
     847    111529613 :   if (code == MEM && !mem_attrs_eq_p (MEM_ATTRS (x), MEM_ATTRS (y)))
     848              :     {
     849        47944 :       if (! MEM_ATTRS (x))
     850          803 :         MEM_ATTRS (y) = 0;
     851        47141 :       else if (! MEM_ATTRS (y))
     852         1358 :         MEM_ATTRS (x) = 0;
     853              :       else
     854              :         {
     855        45783 :           if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y))
     856              :             {
     857         2679 :               set_mem_alias_set (x, 0);
     858         2679 :               set_mem_alias_set (y, 0);
     859              :             }
     860              : 
     861        45783 :           if (! mem_expr_equal_p (MEM_EXPR (x), MEM_EXPR (y)))
     862              :             {
     863        45178 :               set_mem_expr (x, 0);
     864        45178 :               set_mem_expr (y, 0);
     865        45178 :               clear_mem_offset (x);
     866        45178 :               clear_mem_offset (y);
     867              :             }
     868          605 :           else if (MEM_OFFSET_KNOWN_P (x) != MEM_OFFSET_KNOWN_P (y)
     869          605 :                    || (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        52672 :           if (!MEM_SIZE_KNOWN_P (x))
     877          221 :             clear_mem_size (y);
     878        52269 :           else if (!MEM_SIZE_KNOWN_P (y))
     879            8 :             clear_mem_size (x);
     880        45554 :           else if (known_le (MEM_SIZE (x), MEM_SIZE (y)))
     881        45510 :             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        59602 :           set_mem_align (x, MIN (MEM_ALIGN (x), MEM_ALIGN (y)));
     892        52713 :           set_mem_align (y, MEM_ALIGN (x));
     893              :         }
     894              :     }
     895    111529613 :   if (code == MEM)
     896              :     {
     897      6123685 :       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      6123685 :       if (MEM_NOTRAP_P (x) != MEM_NOTRAP_P (y))
     903              :         {
     904          214 :           MEM_NOTRAP_P (x) = 0;
     905          214 :           MEM_NOTRAP_P (y) = 0;
     906              :         }
     907      6123685 :       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    111529613 :   fmt = GET_RTX_FORMAT (code);
     915    338872107 :   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     916              :     {
     917    227342494 :       switch (fmt[i])
     918              :         {
     919       396008 :         case 'E':
     920              :           /* Two vectors must have the same length.  */
     921       396008 :           if (XVECLEN (x, i) != XVECLEN (y, i))
     922              :             return;
     923              : 
     924      1170982 :           for (j = 0; j < XVECLEN (x, i); j++)
     925       774974 :             merge_memattrs (XVECEXP (x, i, j), XVECEXP (y, i, j));
     926              : 
     927              :           break;
     928              : 
     929    139979602 :         case 'e':
     930    139979602 :           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          110 : equal_different_set_p (rtx p1, rtx s1, rtx p2, rtx s2)
     942              : {
     943          110 :   int i;
     944          110 :   rtx e1, e2;
     945              : 
     946          110 :   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      7958658 : values_equal_p (rtx note1, rtx note2, rtx src1, rtx src2)
     983              : {
     984      7958658 :   if (note1
     985      7958658 :       && note2
     986      1285770 :       && CONST_INT_P (XEXP (note1, 0))
     987      8016989 :       && rtx_equal_p (XEXP (note1, 0), XEXP (note2, 0)))
     988              :     return 1;
     989              : 
     990      7958550 :   if (!note1
     991      7958550 :       && !note2
     992      6199589 :       && CONST_INT_P (src1)
     993      2665480 :       && CONST_INT_P (src2)
     994     10521438 :       && rtx_equal_p (src1, src2))
     995              :     return 1;
     996              : 
     997      7958550 :   if (note1
     998      1562556 :       && CONST_INT_P (src2)
     999      8107159 :       && rtx_equal_p (XEXP (note1, 0), src2))
    1000              :     return 1;
    1001              : 
    1002      7958550 :   if (note2
    1003      1482067 :       && CONST_INT_P (src1)
    1004      8029661 :       && rtx_equal_p (XEXP (note2, 0), src1))
    1005            2 :     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     14165656 : can_replace_by (rtx_insn *i1, rtx_insn *i2)
    1017              : {
    1018     14165656 :   rtx s1, s2, d1, d2, src1, src2, note1, note2;
    1019     14165656 :   bool c1, c2;
    1020              : 
    1021              :   /* Check for 2 sets.  */
    1022     14165656 :   s1 = single_set (i1);
    1023     14165656 :   s2 = single_set (i2);
    1024     14165656 :   if (s1 == NULL_RTX || s2 == NULL_RTX)
    1025              :     return dir_none;
    1026              : 
    1027              :   /* Check that the 2 sets set the same dest.  */
    1028     13391427 :   d1 = SET_DEST (s1);
    1029     13391427 :   d2 = SET_DEST (s2);
    1030     26782854 :   if (!(reload_completed
    1031     13391427 :         ? 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      7958658 :   note1 = find_reg_equal_equiv_note (i1);
    1037      7958658 :   note2 = find_reg_equal_equiv_note (i2);
    1038              : 
    1039      7958658 :   src1 = SET_SRC (s1);
    1040      7958658 :   src2 = SET_SRC (s2);
    1041              : 
    1042      7958658 :   if (!values_equal_p (note1, note2, src1, src2))
    1043              :     return dir_none;
    1044              : 
    1045          110 :   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          110 :   c1 = CONST_INT_P (src1);
    1055          110 :   c2 = CONST_INT_P (src2);
    1056          110 :   if (c1 && c2)
    1057              :     return dir_both;
    1058          110 :   else if (c2)
    1059              :     return dir_forward;
    1060          110 :   else if (c1)
    1061            2 :     return dir_backward;
    1062              : 
    1063              :   return dir_none;
    1064              : }
    1065              : 
    1066              : /* Merges directions A and B.  */
    1067              : 
    1068              : static enum replace_direction
    1069     23798082 : 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     16347498 :   if (a == dir_both)
    1083              :     return b;
    1084      3912667 :   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       617547 : insns_have_identical_cfa_notes (rtx_insn *i1, rtx_insn *i2)
    1107              : {
    1108       617547 :   rtx n1, n2;
    1109       617547 :   for (n1 = REG_NOTES (i1), n2 = REG_NOTES (i2); ;
    1110       490090 :        n1 = XEXP (n1, 1), n2 = XEXP (n2, 1))
    1111              :     {
    1112              :       /* Skip over reg notes not related to CFI information.  */
    1113      1622898 :       while (n1 && !reg_note_cfa_p[REG_NOTE_KIND (n1)])
    1114        25171 :         n1 = XEXP (n1, 1);
    1115      1131294 :       while (n2 && !reg_note_cfa_p[REG_NOTE_KIND (n2)])
    1116        23657 :         n2 = XEXP (n2, 1);
    1117      1107637 :       if (n1 == NULL_RTX && n2 == NULL_RTX)
    1118              :         return true;
    1119       601300 :       if (n1 == NULL_RTX || n2 == NULL_RTX)
    1120              :         return false;
    1121       596606 :       if (XEXP (n1, 0) == XEXP (n2, 0))
    1122              :         ;
    1123       596600 :       else if (XEXP (n1, 0) == NULL_RTX || XEXP (n2, 0) == NULL_RTX)
    1124              :         return false;
    1125      1193200 :       else if (!(reload_completed
    1126       596600 :                  ? 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     41217958 : old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx_insn *i1, rtx_insn *i2)
    1139              : {
    1140     41217958 :   rtx p1, p2;
    1141              : 
    1142              :   /* Verify that I1 and I2 are equivalent.  */
    1143     41217958 :   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     35612978 :   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     35525072 :   p1 = find_reg_note (i1, REG_ARGS_SIZE, NULL);
    1153     35525072 :   p2 = find_reg_note (i2, REG_ARGS_SIZE, NULL);
    1154     35525072 :   if (p1 && p2)
    1155              :     {
    1156      3994757 :       p1 = XEXP (p1, 0);
    1157      3994757 :       p2 = XEXP (p2, 0);
    1158      3994757 :       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      3893702 :       if (!frame_pointer_needed
    1164      3893702 :           && known_eq (find_args_size_adjust (i1), HOST_WIDE_INT_MIN))
    1165           27 :         return dir_none;
    1166              :     }
    1167     31530315 :   else if (p1 || p2)
    1168              :     return dir_none;
    1169              : 
    1170              :   /* Do not allow cross-jumping between frame related insns and other
    1171              :      insns.  */
    1172     33818670 :   if (RTX_FRAME_RELATED_P (i1) != RTX_FRAME_RELATED_P (i2))
    1173              :     return dir_none;
    1174              : 
    1175     33377275 :   p1 = PATTERN (i1);
    1176     33377275 :   p2 = PATTERN (i2);
    1177              : 
    1178     33377275 :   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     30786541 :   if (CALL_P (i1))
    1194              :     {
    1195              :       /* Ensure the same EH region.  */
    1196     12391994 :       rtx n1 = find_reg_note (i1, REG_EH_REGION, 0);
    1197     12391994 :       rtx n2 = find_reg_note (i2, REG_EH_REGION, 0);
    1198              : 
    1199     12391994 :       if (!n1 && n2)
    1200              :         return dir_none;
    1201              : 
    1202     12300139 :       if (n1 && (!n2 || XEXP (n1, 0) != XEXP (n2, 0)))
    1203              :         return dir_none;
    1204              : 
    1205     11405911 :       if (!rtx_equal_p (CALL_INSN_FUNCTION_USAGE (i1),
    1206     11405911 :                         CALL_INSN_FUNCTION_USAGE (i2))
    1207      7535125 :           || CALL_INSN_ABI_ID (i1) != CALL_INSN_ABI_ID (i2)
    1208     18941036 :           || 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      7535125 :       if (flag_sanitize & SANITIZE_ADDRESS)
    1214              :         {
    1215       368884 :           rtx call = get_call_rtx_from (i1);
    1216       368884 :           if (call && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
    1217              :             {
    1218       368884 :               rtx symbol = XEXP (XEXP (call, 0), 0);
    1219       368884 :               if (SYMBOL_REF_DECL (symbol)
    1220       368884 :                   && TREE_CODE (SYMBOL_REF_DECL (symbol)) == FUNCTION_DECL)
    1221              :                 {
    1222       368884 :                   if ((DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (symbol))
    1223       368884 :                        == BUILT_IN_NORMAL)
    1224       366879 :                       && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol))
    1225              :                          >= BUILT_IN_ASAN_REPORT_LOAD1
    1226       734255 :                       && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol))
    1227              :                          <= BUILT_IN_ASAN_STOREN)
    1228              :                     return dir_none;
    1229              :                 }
    1230              :             }
    1231              :         }
    1232              : 
    1233      7170704 :       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     25504701 :   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     25393491 :   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     25393491 :   if (reload_completed
    1273     25393491 :       ? rtx_renumbered_equal_p (p1, p2) : rtx_equal_p (p1, p2))
    1274              :     return dir_both;
    1275              : 
    1276     14165656 :   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      8798209 : merge_notes (rtx_insn *i1, rtx_insn *i2)
    1284              : {
    1285              :   /* If the merged insns have different REG_EQUAL notes, then
    1286              :      remove them.  */
    1287      8798209 :   rtx equiv1 = find_reg_equal_equiv_note (i1);
    1288      8798209 :   rtx equiv2 = find_reg_equal_equiv_note (i2);
    1289              : 
    1290      8798209 :   if (equiv1 && !equiv2)
    1291        24185 :     remove_note (i1, equiv1);
    1292      8774024 :   else if (!equiv1 && equiv2)
    1293         5786 :     remove_note (i2, equiv2);
    1294      8768238 :   else if (equiv1 && equiv2
    1295      8768238 :            && !rtx_equal_p (XEXP (equiv1, 0), XEXP (equiv2, 0)))
    1296              :     {
    1297          348 :       remove_note (i1, equiv1);
    1298          348 :       remove_note (i2, equiv2);
    1299              :     }
    1300      8798209 : }
    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     49256844 : walk_to_nondebug_insn (rtx_insn **i1, basic_block *bb1, bool follow_fallthru,
    1310              :                        bool *did_fallthru)
    1311              : {
    1312     49256844 :   edge fallthru;
    1313              : 
    1314     49256844 :   *did_fallthru = false;
    1315              : 
    1316              :   /* Ignore notes.  */
    1317     68669420 :   while (!NONDEBUG_INSN_P (*i1))
    1318              :     {
    1319     20646576 :       if (*i1 != BB_HEAD (*bb1))
    1320              :         {
    1321     19226495 :           *i1 = PREV_INSN (*i1);
    1322     19226495 :           continue;
    1323              :         }
    1324              : 
    1325      1420081 :       if (!follow_fallthru)
    1326              :         return;
    1327              : 
    1328      1234919 :       fallthru = find_fallthru_edge ((*bb1)->preds);
    1329       477718 :       if (!fallthru || fallthru->src == ENTRY_BLOCK_PTR_FOR_FN (cfun)
    1330      1712561 :           || !single_succ_p (fallthru->src))
    1331              :         return;
    1332              : 
    1333       186081 :       *bb1 = fallthru->src;
    1334       186081 :       *i1 = BB_END (*bb1);
    1335       186081 :       *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     16049269 : flow_find_cross_jump (basic_block bb1, basic_block bb2, rtx_insn **f1,
    1353              :                       rtx_insn **f2, enum replace_direction *dir_p)
    1354              : {
    1355     16049269 :   rtx_insn *i1, *i2, *last1, *last2, *afterlast1, *afterlast2;
    1356     16049269 :   int ninsns = 0;
    1357     16049269 :   enum replace_direction dir, last_dir, afterlast_dir;
    1358     16049269 :   bool follow_fallthru, did_fallthru;
    1359              : 
    1360     16049269 :   if (dir_p)
    1361     16049269 :     dir = *dir_p;
    1362              :   else
    1363              :     dir = dir_both;
    1364     16049269 :   afterlast_dir = dir;
    1365     16049269 :   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     16049269 :   i1 = BB_END (bb1);
    1371     16049269 :   last1 = afterlast1 = last2 = afterlast2 = NULL;
    1372     16049269 :   if (onlyjump_p (i1)
    1373     16049269 :       || (returnjump_p (i1) && !side_effects_p (PATTERN (i1))))
    1374              :     {
    1375     14381895 :       last1 = i1;
    1376     14381895 :       i1 = PREV_INSN (i1);
    1377              :     }
    1378              : 
    1379     16049269 :   i2 = BB_END (bb2);
    1380     16049269 :   if (onlyjump_p (i2)
    1381     16049269 :       || (returnjump_p (i2) && !side_effects_p (PATTERN (i2))))
    1382              :     {
    1383     11647576 :       last2 = i2;
    1384              :       /* Count everything except for unconditional jump as insn.
    1385              :          Don't count any jumps if dir_p is NULL.  */
    1386     11647576 :       if (!simplejump_p (i2) && !returnjump_p (i2) && last1 && dir_p)
    1387              :         ninsns++;
    1388     11647576 :       i2 = PREV_INSN (i2);
    1389              :     }
    1390              : 
    1391     33207575 :   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     24628422 :       follow_fallthru = dir_p && dir != dir_forward;
    1410     24628422 :       walk_to_nondebug_insn (&i1, &bb1, follow_fallthru, &did_fallthru);
    1411     24628422 :       if (did_fallthru)
    1412        28481 :         dir = dir_backward;
    1413              : 
    1414     24628422 :       follow_fallthru = dir_p && dir != dir_backward;
    1415     24628422 :       walk_to_nondebug_insn (&i2, &bb2, follow_fallthru, &did_fallthru);
    1416     24628422 :       if (did_fallthru)
    1417       157590 :         dir = dir_forward;
    1418              : 
    1419     24628422 :       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     23798082 :       if (BB_PARTITION (BLOCK_FOR_INSN (i1))
    1425     23798082 :           != BB_PARTITION (BLOCK_FOR_INSN (i2))
    1426     23798082 :           && reload_completed)
    1427              :         break;
    1428              : 
    1429     23798082 :       dir = merge_dir (dir, old_insns_match_p (0, i1, i2));
    1430     21013984 :       if (dir == dir_none || (!dir_p && dir != dir_both))
    1431              :         break;
    1432              : 
    1433      8579153 :       merge_memattrs (i1, i2);
    1434              : 
    1435              :       /* Don't begin a cross-jump with a NOTE insn.  */
    1436      8579153 :       if (INSN_P (i1))
    1437              :         {
    1438      8579153 :           merge_notes (i1, i2);
    1439              : 
    1440      8579153 :           afterlast1 = last1, afterlast2 = last2;
    1441      8579153 :           last1 = i1, last2 = i2;
    1442      8579153 :           afterlast_dir = last_dir;
    1443      8579153 :           last_dir = dir;
    1444      8579153 :           if (active_insn_p (i1))
    1445      8475560 :             ninsns++;
    1446              :         }
    1447              : 
    1448      8579153 :       i1 = PREV_INSN (i1);
    1449      8579153 :       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     16049269 :   if (ninsns)
    1456              :     {
    1457      5177897 :       bb1 = BLOCK_FOR_INSN (last1);
    1458     13392817 :       while (last1 != BB_HEAD (bb1) && !NONDEBUG_INSN_P (PREV_INSN (last1)))
    1459              :         last1 = PREV_INSN (last1);
    1460              : 
    1461     10060417 :       if (last1 != BB_HEAD (bb1) && LABEL_P (PREV_INSN (last1)))
    1462              :         last1 = PREV_INSN (last1);
    1463              : 
    1464      5177897 :       bb2 = BLOCK_FOR_INSN (last2);
    1465     13442112 :       while (last2 != BB_HEAD (bb2) && !NONDEBUG_INSN_P (PREV_INSN (last2)))
    1466              :         last2 = PREV_INSN (last2);
    1467              : 
    1468      9769262 :       if (last2 != BB_HEAD (bb2) && LABEL_P (PREV_INSN (last2)))
    1469              :         last2 = PREV_INSN (last2);
    1470              : 
    1471      5177897 :       *f1 = last1;
    1472      5177897 :       *f2 = last2;
    1473              :     }
    1474              : 
    1475     16049269 :   if (dir_p)
    1476     16049269 :     *dir_p = last_dir;
    1477     16049269 :   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      4696632 : flow_find_head_matching_sequence (basic_block bb1, basic_block bb2, rtx_insn **f1,
    1488              :                                   rtx_insn **f2, int stop_after)
    1489              : {
    1490      4696632 :   rtx_insn *i1, *i2, *last1, *last2, *beforelast1, *beforelast2;
    1491      4696632 :   int ninsns = 0;
    1492      4696632 :   edge e;
    1493      4696632 :   edge_iterator ei;
    1494      4696632 :   int nehedges1 = 0, nehedges2 = 0;
    1495              : 
    1496     11265394 :   FOR_EACH_EDGE (e, ei, bb1->succs)
    1497      6568762 :     if (e->flags & EDGE_EH)
    1498       353432 :       nehedges1++;
    1499     11624080 :   FOR_EACH_EDGE (e, ei, bb2->succs)
    1500      6927448 :     if (e->flags & EDGE_EH)
    1501       384916 :       nehedges2++;
    1502              : 
    1503      4696632 :   i1 = BB_HEAD (bb1);
    1504      4696632 :   i2 = BB_HEAD (bb2);
    1505      4696632 :   last1 = beforelast1 = last2 = beforelast2 = NULL;
    1506              : 
    1507       205311 :   while (true)
    1508              :     {
    1509              :       /* Ignore notes, except NOTE_INSN_EPILOGUE_BEG.  */
    1510     23212613 :       while (!NONDEBUG_INSN_P (i1) && i1 != BB_END (bb1))
    1511              :         {
    1512     18129409 :           if (NOTE_P (i1) && NOTE_KIND (i1) == NOTE_INSN_EPILOGUE_BEG)
    1513              :             break;
    1514     18105359 :           i1 = NEXT_INSN (i1);
    1515              :         }
    1516              : 
    1517     22909316 :       while (!NONDEBUG_INSN_P (i2) && i2 != BB_END (bb2))
    1518              :         {
    1519     18054629 :           if (NOTE_P (i2) && NOTE_KIND (i2) == NOTE_INSN_EPILOGUE_BEG)
    1520              :             break;
    1521     18007373 :           i2 = NEXT_INSN (i2);
    1522              :         }
    1523              : 
    1524      4901943 :       if ((i1 == BB_END (bb1) && !NONDEBUG_INSN_P (i1))
    1525      4889706 :           || (i2 == BB_END (bb2) && !NONDEBUG_INSN_P (i2)))
    1526              :         break;
    1527              : 
    1528      4884802 :       if (NOTE_P (i1) || NOTE_P (i2)
    1529      4819388 :           || 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      3952855 :       if ((i1 == BB_END (bb1) && i2 != BB_END (bb2)
    1537       217592 :            && nehedges1 > 0)
    1538      3915341 :           || (i2 == BB_END (bb2) && i1 != BB_END (bb1)
    1539       250855 :               && nehedges2 > 0)
    1540      3886690 :           || (i1 == BB_END (bb1) && i2 == BB_END (bb2)
    1541        25315 :               && nehedges1 != nehedges2))
    1542              :         break;
    1543              : 
    1544      3883937 :       if (old_insns_match_p (0, i1, i2) != dir_both)
    1545              :         break;
    1546              : 
    1547       219056 :       merge_memattrs (i1, i2);
    1548              : 
    1549              :       /* Don't begin a cross-jump with a NOTE insn.  */
    1550       219056 :       if (INSN_P (i1))
    1551              :         {
    1552       219056 :           merge_notes (i1, i2);
    1553              : 
    1554       219056 :           beforelast1 = last1, beforelast2 = last2;
    1555       219056 :           last1 = i1, last2 = i2;
    1556       219056 :           if (!stop_after || active_insn_p (i1))
    1557       219056 :             ninsns++;
    1558              :         }
    1559              : 
    1560       219056 :       if (i1 == BB_END (bb1) || i2 == BB_END (bb2)
    1561       205311 :           || (stop_after > 0 && ninsns == stop_after))
    1562              :         break;
    1563              : 
    1564       205311 :       i1 = NEXT_INSN (i1);
    1565       205311 :       i2 = NEXT_INSN (i2);
    1566              :     }
    1567              : 
    1568      4696632 :   if (ninsns)
    1569              :     {
    1570       125051 :       *f1 = last1;
    1571       125051 :       *f2 = last2;
    1572              :     }
    1573              : 
    1574      4696632 :   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     47740121 : outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
    1585              : {
    1586     47740121 :   int nehedges1 = 0, nehedges2 = 0;
    1587     47740121 :   edge fallthru1 = 0, fallthru2 = 0;
    1588     47740121 :   edge e1, e2;
    1589     47740121 :   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     47740121 :   if (crtl->shrink_wrapped
    1596      1234674 :       && single_succ_p (bb1)
    1597       471591 :       && single_succ (bb1) == EXIT_BLOCK_PTR_FOR_FN (cfun)
    1598       151681 :       && (!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        64113 :           || (single_succ_edge (bb1)->flags & EDGE_FAKE) != 0)
    1602     47827769 :       && !(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     47690240 :   if (single_succ_p (bb1)
    1608     19067445 :       && (single_succ_edge (bb1)->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0
    1609     63161270 :       && (!JUMP_P (BB_END (bb1)) || simplejump_p (BB_END (bb1))))
    1610     15209541 :     return (single_succ_p (bb2)
    1611     13989749 :             && (single_succ_edge (bb2)->flags
    1612     13989749 :                 & (EDGE_COMPLEX | EDGE_FAKE)) == 0
    1613     29118431 :             && (!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     32480699 :   if (EDGE_COUNT (bb1->succs) == 2
    1618     28524610 :       && any_condjump_p (BB_END (bb1))
    1619     51423528 :       && onlyjump_p (BB_END (bb1)))
    1620              :     {
    1621     18942829 :       edge b1, f1, b2, f2;
    1622     18942829 :       bool reverse, match;
    1623     18942829 :       rtx set1, set2, cond1, cond2;
    1624     18942829 :       enum rtx_code code1, code2;
    1625              : 
    1626     18942829 :       if (EDGE_COUNT (bb2->succs) != 2
    1627      8530262 :           || !any_condjump_p (BB_END (bb2))
    1628     27433020 :           || !onlyjump_p (BB_END (bb2)))
    1629              :         return false;
    1630              : 
    1631      8490191 :       b1 = BRANCH_EDGE (bb1);
    1632      8490191 :       b2 = BRANCH_EDGE (bb2);
    1633      8490191 :       f1 = FALLTHRU_EDGE (bb1);
    1634      8490191 :       f2 = FALLTHRU_EDGE (bb2);
    1635              : 
    1636              :       /* Get around possible forwarders on fallthru edges.  Other cases
    1637              :          should be optimized out already.  */
    1638      8490191 :       if (FORWARDER_BLOCK_P (f1->dest))
    1639      3300326 :         f1 = single_succ_edge (f1->dest);
    1640              : 
    1641      8490191 :       if (FORWARDER_BLOCK_P (f2->dest))
    1642      2438971 :         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      8490191 :       if (FORWARDER_BLOCK_P (f1->dest)
    1648      8481132 :           || FORWARDER_BLOCK_P (f2->dest)
    1649      8476396 :           || FORWARDER_BLOCK_P (b1->dest)
    1650      8452844 :           || FORWARDER_BLOCK_P (b2->dest))
    1651              :         return false;
    1652              : 
    1653      8424623 :       if (f1->dest == f2->dest && b1->dest == b2->dest)
    1654              :         reverse = false;
    1655      8213185 :       else if (f1->dest == b2->dest && b1->dest == f2->dest)
    1656              :         reverse = true;
    1657              :       else
    1658              :         return false;
    1659              : 
    1660       355770 :       set1 = pc_set (BB_END (bb1));
    1661       355770 :       set2 = pc_set (BB_END (bb2));
    1662       355770 :       if ((XEXP (SET_SRC (set1), 1) == pc_rtx)
    1663       355770 :           != (XEXP (SET_SRC (set2), 1) == pc_rtx))
    1664            0 :         reverse = !reverse;
    1665              : 
    1666       355770 :       cond1 = XEXP (SET_SRC (set1), 0);
    1667       355770 :       cond2 = XEXP (SET_SRC (set2), 0);
    1668       355770 :       code1 = GET_CODE (cond1);
    1669       355770 :       if (reverse)
    1670       144332 :         code2 = reversed_comparison_code (cond2, BB_END (bb2));
    1671              :       else
    1672       211438 :         code2 = GET_CODE (cond2);
    1673              : 
    1674       355770 :       if (code2 == UNKNOWN)
    1675              :         return false;
    1676              : 
    1677              :       /* Verify codes and operands match.  */
    1678       355770 :       match = ((code1 == code2
    1679       304102 :                 && rtx_renumbered_equal_p (XEXP (cond1, 0), XEXP (cond2, 0))
    1680       302032 :                 && rtx_renumbered_equal_p (XEXP (cond1, 1), XEXP (cond2, 1)))
    1681       357840 :                || (code1 == swap_condition (code2)
    1682         4783 :                    && rtx_renumbered_equal_p (XEXP (cond1, 1),
    1683         4783 :                                               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              :       if (match
    1692       302032 :           && optimize_bb_for_speed_p (bb1)
    1693       273978 :           && optimize_bb_for_speed_p (bb2))
    1694              :         {
    1695       263896 :           profile_probability prob2;
    1696              : 
    1697       263896 :           if (b1->dest == b2->dest)
    1698       159362 :             prob2 = b2->probability;
    1699              :           else
    1700              :             /* Do not use f2 probability as f2 may be forwarded.  */
    1701       104534 :             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       263896 :           if (b1->probability.differs_lot_from_p (prob2))
    1707              :             {
    1708         2528 :               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         2528 :               return false;
    1718              :             }
    1719              :         }
    1720              : 
    1721       353242 :       if (dump_file && match)
    1722           16 :         fprintf (dump_file, "Conditionals in bb %i and %i match.\n",
    1723              :                  bb1->index, bb2->index);
    1724              : 
    1725              :       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     13537870 :     {
    1734     13537870 :       rtx_insn *label1, *label2;
    1735     13537870 :       rtx_jump_table_data *table1, *table2;
    1736              : 
    1737     13537870 :       if (tablejump_p (BB_END (bb1), &label1, &table1)
    1738        95602 :           && tablejump_p (BB_END (bb2), &label2, &table2)
    1739     13540038 :           && 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         2168 :           if (label1 != label2 && !rtx_referenced_p (label2, BB_END (bb1)))
    1749              :             {
    1750              :               /* Set IDENTICAL to true when the tables are identical.  */
    1751         2168 :               bool identical = false;
    1752         2168 :               rtx p1, p2;
    1753              : 
    1754         2168 :               p1 = PATTERN (table1);
    1755         2168 :               p2 = PATTERN (table2);
    1756         2168 :               if (GET_CODE (p1) == ADDR_VEC && rtx_equal_p (p1, p2))
    1757              :                 {
    1758              :                   identical = true;
    1759              :                 }
    1760         1979 :               else if (GET_CODE (p1) == ADDR_DIFF_VEC
    1761          389 :                        && (XVECLEN (p1, 1) == XVECLEN (p2, 1))
    1762          267 :                        && rtx_equal_p (XEXP (p1, 2), XEXP (p2, 2))
    1763         2246 :                        && rtx_equal_p (XEXP (p1, 3), XEXP (p2, 3)))
    1764              :                 {
    1765          267 :                   int i;
    1766              : 
    1767          267 :                   identical = true;
    1768         1170 :                   for (i = XVECLEN (p1, 1) - 1; i >= 0 && identical; i--)
    1769          903 :                     if (!rtx_equal_p (XVECEXP (p1, 1, i), XVECEXP (p2, 1, i)))
    1770              :                       identical = false;
    1771              :                 }
    1772              : 
    1773          267 :               if (identical)
    1774              :                 {
    1775          237 :                   bool match;
    1776              : 
    1777              :                   /* Temporarily replace references to LABEL1 with LABEL2
    1778              :                      in BB1->END so that we could compare the instructions.  */
    1779          237 :                   replace_label_in_insn (BB_END (bb1), label1, label2, false);
    1780              : 
    1781          237 :                   match = (old_insns_match_p (mode, BB_END (bb1), BB_END (bb2))
    1782              :                            == dir_both);
    1783          237 :                   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          237 :                   replace_label_in_insn (BB_END (bb1), label2, label1, false);
    1792              : 
    1793         2168 :                   return match;
    1794              :                 }
    1795              :             }
    1796              :           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     13535702 :   rtx_insn *last1 = BB_END (bb1);
    1805     13535702 :   rtx_insn *last2 = BB_END (bb2);
    1806     13535793 :   while (!NOTE_INSN_BASIC_BLOCK_P (last1) &&
    1807     13405251 :          (DEBUG_INSN_P (last1) || NOTE_P (last1)))
    1808           91 :     last1 = PREV_INSN (last1);
    1809     13554176 :   while (!NOTE_INSN_BASIC_BLOCK_P (last2) &&
    1810     13441312 :          (DEBUG_INSN_P (last2) || NOTE_P (last2)))
    1811        18474 :     last2 = PREV_INSN (last2);
    1812     13535702 :   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     13535702 :   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      7551918 :   if (EDGE_COUNT (bb1->succs) != EDGE_COUNT (bb2->succs))
    1823              :     return false;
    1824              : 
    1825      2517293 :   bool nonfakeedges = false;
    1826      6212165 :   FOR_EACH_EDGE (e1, ei, bb1->succs)
    1827              :     {
    1828      3694872 :       e2 = EDGE_SUCC (bb2, ei.index);
    1829              : 
    1830      3694872 :       if ((e1->flags & EDGE_FAKE) == 0)
    1831      2708404 :         nonfakeedges = true;
    1832              : 
    1833      3694872 :       if (e1->flags & EDGE_EH)
    1834      1223378 :         nehedges1++;
    1835              : 
    1836      3694872 :       if (e2->flags & EDGE_EH)
    1837      1223378 :         nehedges2++;
    1838              : 
    1839      3694872 :       if (e1->flags & EDGE_FALLTHRU)
    1840      1273600 :         fallthru1 = e1;
    1841      3694872 :       if (e2->flags & EDGE_FALLTHRU)
    1842      1273600 :         fallthru2 = e2;
    1843              :     }
    1844              : 
    1845              :   /* If number of edges of various types does not match, fail.  */
    1846      2517293 :   if (nehedges1 != nehedges2
    1847      2517293 :       || (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      2517293 :   if (!nonfakeedges
    1857       986468 :       && !ACCUMULATE_OUTGOING_ARGS
    1858      3503754 :       && (!INSN_P (last1)
    1859       986461 :           || !find_reg_note (last1, REG_ARGS_SIZE, NULL)))
    1860              :     return false;
    1861              : 
    1862              :   /* fallthru edges must be forwarded to the same destination.  */
    1863      2517282 :   if (fallthru1)
    1864              :     {
    1865      1273600 :       basic_block d1 = (FORWARDER_BLOCK_P (fallthru1->dest)
    1866      1273600 :                         ? single_succ (fallthru1->dest) : fallthru1->dest);
    1867      1273600 :       basic_block d2 = (FORWARDER_BLOCK_P (fallthru2->dest)
    1868      1273600 :                         ? single_succ (fallthru2->dest) : fallthru2->dest);
    1869              : 
    1870      1273600 :       if (d1 != d2)
    1871              :         return false;
    1872              :     }
    1873              : 
    1874              :   /* Ensure the same EH region.  */
    1875      1840680 :   {
    1876      1840680 :     rtx n1 = find_reg_note (last1, REG_EH_REGION, 0);
    1877      1840680 :     rtx n2 = find_reg_note (last2, REG_EH_REGION, 0);
    1878              : 
    1879      1840680 :     if (!n1 && n2)
    1880              :       return false;
    1881              : 
    1882      1840680 :     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      4181695 :   FOR_EACH_EDGE (e1, ei, bb2->succs)
    1889              :     {
    1890      2341045 :       edge e2;
    1891      2341045 :       edge_iterator ei;
    1892      2341045 :       basic_block d1 = e1->dest;
    1893              : 
    1894      2341045 :       if (FORWARDER_BLOCK_P (d1))
    1895       615209 :         d1 = EDGE_SUCC (d1, 0)->dest;
    1896              : 
    1897      2842880 :       FOR_EACH_EDGE (e2, ei, bb1->succs)
    1898              :         {
    1899      2842880 :           basic_block d2 = e2->dest;
    1900      2842880 :           if (FORWARDER_BLOCK_P (d2))
    1901       801159 :             d2 = EDGE_SUCC (d2, 0)->dest;
    1902      2842880 :           if (d1 == d2)
    1903              :             break;
    1904              :         }
    1905              : 
    1906      2341045 :       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       385009 : block_has_preserve_label (basic_block bb)
    1917              : {
    1918       385009 :   return (bb
    1919       385009 :           && block_label (bb)
    1920       717372 :           && 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     52636356 : try_crossjump_to_edge (int mode, edge e1, edge e2,
    1931              :                        enum replace_direction dir)
    1932              : {
    1933     52636356 :   int nmatch;
    1934     52636356 :   basic_block src1 = e1->src, src2 = e2->src;
    1935     52636356 :   basic_block redirect_to, redirect_from, to_remove;
    1936     52636356 :   basic_block osrc1, osrc2, redirect_edges_to, tmp;
    1937     52636356 :   rtx_insn *newpos1, *newpos2;
    1938     52636356 :   edge s;
    1939     52636356 :   edge_iterator ei;
    1940              : 
    1941     52636356 :   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     52636356 :   if (single_pred_p (src1)
    1948     52636356 :       && FORWARDER_BLOCK_P (src1))
    1949     11836720 :     e1 = single_pred_edge (src1), src1 = e1->src;
    1950              : 
    1951     52636356 :   if (single_pred_p (src2)
    1952     52636144 :       && FORWARDER_BLOCK_P (src2))
    1953      5562252 :     e2 = single_pred_edge (src2), src2 = e2->src;
    1954              : 
    1955              :   /* Nothing to do if we reach ENTRY, or a common source block.  */
    1956     52636356 :   if (src1 == ENTRY_BLOCK_PTR_FOR_FN (cfun) || src2
    1957              :       == ENTRY_BLOCK_PTR_FOR_FN (cfun))
    1958              :     return false;
    1959     52635940 :   if (src1 == src2)
    1960              :     return false;
    1961              : 
    1962              :   /* Seeing more than 1 forwarder blocks would confuse us later...  */
    1963     52635811 :   if (FORWARDER_BLOCK_P (e1->dest)
    1964     52635811 :       && FORWARDER_BLOCK_P (single_succ (e1->dest)))
    1965              :     return false;
    1966              : 
    1967     52624206 :   if (FORWARDER_BLOCK_P (e2->dest)
    1968     52624206 :       && 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     52623656 :   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     47948371 :   if (BB_PARTITION (src1) != BB_PARTITION (src2)
    1978       208250 :       && reload_completed)
    1979              :     return false;
    1980              : 
    1981              :   /* Look for the common insn sequence, part the first ...  */
    1982     47740121 :   if (!outgoing_edges_match (mode, src1, src2))
    1983              :     return false;
    1984              : 
    1985              :   /* ... and part the second.  */
    1986     16049269 :   nmatch = flow_find_cross_jump (src1, src2, &newpos1, &newpos2, &dir);
    1987              : 
    1988     16049269 :   osrc1 = src1;
    1989     16049269 :   osrc2 = src2;
    1990     16049269 :   if (newpos1 != NULL_RTX)
    1991      5177897 :     src1 = BLOCK_FOR_INSN (newpos1);
    1992     16049269 :   if (newpos2 != NULL_RTX)
    1993      5177897 :     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     16049269 :   if (EDGE_COUNT (src1->preds) == 0 || EDGE_COUNT (src2->preds) == 0)
    1998              :     return false;
    1999              : 
    2000     16049269 :   if (dir == dir_backward)
    2001              :     {
    2002         1748 :       std::swap (osrc1, osrc2);
    2003         1748 :       std::swap (src1, src2);
    2004         1748 :       std::swap (e1, e2);
    2005         1748 :       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     16049269 :   if ((nmatch < param_min_crossjump_insns)
    2013     15918714 :       && (newpos1 != BB_HEAD (src1)))
    2014              :     return false;
    2015              : 
    2016              :   /* Avoid deleting preserve label when redirecting ABNORMAL edges.  */
    2017       385009 :   if (block_has_preserve_label (e1->dest)
    2018       385009 :       && (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       343563 :   {
    2027       343563 :       rtx_insn *label1, *label2;
    2028       343563 :       rtx_jump_table_data *table1, *table2;
    2029              : 
    2030       343563 :       if (tablejump_p (BB_END (osrc1), &label1, &table1)
    2031          189 :           && tablejump_p (BB_END (osrc2), &label2, &table2)
    2032       343752 :           && label1 != label2)
    2033              :         {
    2034          189 :           rtx_insn *insn;
    2035              : 
    2036              :           /* Replace references to LABEL1 with LABEL2.  */
    2037       565644 :           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       565455 :               if (insn != BB_END (osrc1))
    2043       565266 :                 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       343563 :   if (newpos2 == BB_HEAD (src2)
    2052       343563 :       && !(EDGE_PRED (src2, 0)->flags & EDGE_EH))
    2053              :     redirect_to = src2;
    2054              :   else
    2055              :     {
    2056        89662 :       if (newpos2 == BB_HEAD (src2))
    2057              :         {
    2058              :           /* Skip possible basic block header.  */
    2059         6619 :           if (LABEL_P (newpos2))
    2060         6619 :             newpos2 = NEXT_INSN (newpos2);
    2061         6619 :           while (DEBUG_INSN_P (newpos2))
    2062            0 :             newpos2 = NEXT_INSN (newpos2);
    2063         6619 :           if (NOTE_P (newpos2))
    2064         6619 :             newpos2 = NEXT_INSN (newpos2);
    2065         6815 :           while (DEBUG_INSN_P (newpos2))
    2066          196 :             newpos2 = NEXT_INSN (newpos2);
    2067              :         }
    2068              : 
    2069        89662 :       if (dump_file)
    2070            2 :         fprintf (dump_file, "Splitting bb %i before %i insns\n",
    2071              :                  src2->index, nmatch);
    2072        89662 :       redirect_to = split_block (src2, PREV_INSN (newpos2))->dest;
    2073              :     }
    2074              : 
    2075       343563 :   if (dump_file)
    2076           42 :     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       343563 :   df_set_bb_dirty (redirect_to);
    2082              : 
    2083       343563 :   if (osrc2 == src2)
    2084              :     redirect_edges_to = redirect_to;
    2085              :   else
    2086        10480 :     redirect_edges_to = osrc2;
    2087              : 
    2088              :   /* Recompute the counts of destinations of outgoing edges.  */
    2089       759621 :   FOR_EACH_EDGE (s, ei, redirect_edges_to->succs)
    2090              :     {
    2091       416058 :       edge s2;
    2092       416058 :       edge_iterator ei;
    2093       416058 :       basic_block d = s->dest;
    2094              : 
    2095       416058 :       if (FORWARDER_BLOCK_P (d))
    2096        30889 :         d = single_succ (d);
    2097              : 
    2098       497082 :       FOR_EACH_EDGE (s2, ei, src1->succs)
    2099              :         {
    2100       497082 :           basic_block d2 = s2->dest;
    2101       497082 :           if (FORWARDER_BLOCK_P (d2))
    2102       104836 :             d2 = single_succ (d2);
    2103       497082 :           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       416058 :       if (FORWARDER_BLOCK_P (s->dest))
    2111        30889 :         s->dest->count += s->count ();
    2112              : 
    2113       416058 :       if (FORWARDER_BLOCK_P (s2->dest))
    2114        81025 :         s2->dest->count -= s->count ();
    2115              : 
    2116       416058 :       s->probability = s->probability.combine_with_count
    2117       416058 :                           (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       365759 :   do
    2127              :     {
    2128       354661 :       tmp->count += src1->count;
    2129       354661 :       if (tmp == redirect_edges_to)
    2130              :         break;
    2131        11098 :       tmp = find_fallthru_edge (tmp->succs)->dest;
    2132              :     }
    2133              :   while (true);
    2134       343563 :   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       343563 :   if (LABEL_P (newpos1))
    2140       143707 :     newpos1 = NEXT_INSN (newpos1);
    2141              : 
    2142       358887 :   while (DEBUG_INSN_P (newpos1))
    2143        15324 :     newpos1 = NEXT_INSN (newpos1);
    2144              : 
    2145       343563 :   if (NOTE_INSN_BASIC_BLOCK_P (newpos1))
    2146       258225 :     newpos1 = NEXT_INSN (newpos1);
    2147              : 
    2148              :   /* Skip also prologue and function markers.  */
    2149      1042191 :   while (DEBUG_INSN_P (newpos1)
    2150      1042191 :          || (NOTE_P (newpos1)
    2151        16387 :              && (NOTE_KIND (newpos1) == NOTE_INSN_PROLOGUE_END
    2152        16387 :                  || NOTE_KIND (newpos1) == NOTE_INSN_FUNCTION_BEG)))
    2153       698628 :     newpos1 = NEXT_INSN (newpos1);
    2154              : 
    2155       343563 :   redirect_from = split_block (src1, PREV_INSN (newpos1))->src;
    2156       343563 :   to_remove = single_succ (redirect_from);
    2157              : 
    2158       343563 :   redirect_edge_and_branch_force (single_succ_edge (redirect_from), redirect_to);
    2159       343563 :   delete_basic_block (to_remove);
    2160              : 
    2161       343563 :   update_forwarder_flag (redirect_from);
    2162       343563 :   if (redirect_to != src2)
    2163        89662 :     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     31371776 : try_crossjump_bb (int mode, basic_block bb)
    2174              : {
    2175     31371776 :   edge e, e2, fallthru;
    2176     31371776 :   bool changed;
    2177     31371776 :   unsigned max, ix, ix2;
    2178              : 
    2179              :   /* Nothing to do if there is not at least two incoming edges.  */
    2180     31371776 :   if (EDGE_COUNT (bb->preds) < 2)
    2181              :     return false;
    2182              : 
    2183              :   /* Don't crossjump the predecessors of a computed jump when computed
    2184              :      gotos are duplicated (see pass_duplicate_computed_gotos::gate), as
    2185              :      that copies the jump back into each predecessor.  */
    2186      8612885 :   if (!optimize_function_for_size_p (cfun)
    2187      8404794 :       && flag_expensive_optimizations
    2188      8404617 :       && bb != EXIT_BLOCK_PTR_FOR_FN (cfun)
    2189     16551225 :       && computed_jump_p (BB_END (bb)))
    2190              :     return false;
    2191              : 
    2192              :   /* If we are partitioning hot/cold basic blocks, we don't want to
    2193              :      mess up unconditional or indirect jumps that cross between hot
    2194              :      and cold sections.
    2195              : 
    2196              :      Basic block partitioning may result in some jumps that appear to
    2197              :      be optimizable (or blocks that appear to be mergeable), but which really
    2198              :      must be left untouched (they are required to make it safely across
    2199              :      partition boundaries).  See the comments at the top of
    2200              :      bb-reorder.cc:partition_hot_cold_basic_blocks for complete details.  */
    2201              : 
    2202      8612771 :   if (BB_PARTITION (EDGE_PRED (bb, 0)->src) !=
    2203      8612771 :                                         BB_PARTITION (EDGE_PRED (bb, 1)->src)
    2204      8612771 :       || (EDGE_PRED (bb, 0)->flags & EDGE_CROSSING))
    2205              :     return false;
    2206              : 
    2207              :   /* It is always cheapest to redirect a block that ends in a branch to
    2208              :      a block that falls through into BB, as that adds no branches to the
    2209              :      program.  We'll try that combination first.  */
    2210      8395257 :   fallthru = NULL;
    2211      8395257 :   max = param_max_crossjump_edges;
    2212              : 
    2213      8395257 :   if (EDGE_COUNT (bb->preds) > max)
    2214              :     return false;
    2215              : 
    2216      8392318 :   fallthru = find_fallthru_edge (bb->preds);
    2217              : 
    2218      8392318 :   changed = false;
    2219     41244352 :   for (ix = 0; ix < EDGE_COUNT (bb->preds);)
    2220              :     {
    2221     24459716 :       e = EDGE_PRED (bb, ix);
    2222     24459716 :       ix++;
    2223              : 
    2224              :       /* As noted above, first try with the fallthru predecessor (or, a
    2225              :          fallthru predecessor if we are in cfglayout mode).  */
    2226     24459716 :       if (fallthru)
    2227              :         {
    2228              :           /* Don't combine the fallthru edge into anything else.
    2229              :              If there is a match, we'll do it the other way around.  */
    2230     17968357 :           if (e == fallthru)
    2231      6771601 :             continue;
    2232              :           /* If nothing changed since the last attempt, there is nothing
    2233              :              we can do.  */
    2234     11196756 :           if (!first_pass
    2235      4422429 :               && !((e->src->flags & BB_MODIFIED)
    2236      3517014 :                    || (fallthru->src->flags & BB_MODIFIED)))
    2237      3144258 :             continue;
    2238              : 
    2239      8052498 :           if (try_crossjump_to_edge (mode, e, fallthru, dir_forward))
    2240              :             {
    2241       152646 :               changed = true;
    2242       152646 :               ix = 0;
    2243       152646 :               continue;
    2244              :             }
    2245              :         }
    2246              : 
    2247              :       /* Non-obvious work limiting check: Recognize that we're going
    2248              :          to call try_crossjump_bb on every basic block.  So if we have
    2249              :          two blocks with lots of outgoing edges (a switch) and they
    2250              :          share lots of common destinations, then we would do the
    2251              :          cross-jump check once for each common destination.
    2252              : 
    2253              :          Now, if the blocks actually are cross-jump candidates, then
    2254              :          all of their destinations will be shared.  Which means that
    2255              :          we only need check them for cross-jump candidacy once.  We
    2256              :          can eliminate redundant checks of crossjump(A,B) by arbitrarily
    2257              :          choosing to do the check from the block for which the edge
    2258              :          in question is the first successor of A.  */
    2259     14391211 :       if (EDGE_SUCC (e->src, 0) != e)
    2260      2982639 :         continue;
    2261              : 
    2262    172695956 :       for (ix2 = 0; ix2 < EDGE_COUNT (bb->preds); ix2++)
    2263              :         {
    2264    128626267 :           e2 = EDGE_PRED (bb, ix2);
    2265              : 
    2266    128626267 :           if (e2 == e)
    2267     11316748 :             continue;
    2268              : 
    2269              :           /* We've already checked the fallthru edge above.  */
    2270    117309519 :           if (e2 == fallthru)
    2271      6297868 :             continue;
    2272              : 
    2273              :           /* The "first successor" check above only prevents multiple
    2274              :              checks of crossjump(A,B).  In order to prevent redundant
    2275              :              checks of crossjump(B,A), require that A be the block
    2276              :              with the lowest index.  */
    2277    111011651 :           if (e->src->index > e2->src->index)
    2278     55383093 :             continue;
    2279              : 
    2280              :           /* If nothing changed since the last attempt, there is nothing
    2281              :              we can do.  */
    2282     55628558 :           if (!first_pass
    2283     14093773 :               && !((e->src->flags & BB_MODIFIED)
    2284     11920159 :                    || (e2->src->flags & BB_MODIFIED)))
    2285     11044700 :             continue;
    2286              : 
    2287              :           /* Both e and e2 are not fallthru edges, so we can crossjump in either
    2288              :              direction.  */
    2289     44583858 :           if (try_crossjump_to_edge (mode, e, e2, dir_both))
    2290              :             {
    2291              :               changed = true;
    2292              :               ix = 0;
    2293              :               break;
    2294              :             }
    2295              :         }
    2296              :     }
    2297              : 
    2298      8392318 :   if (changed)
    2299       168336 :     crossjumps_occurred = true;
    2300              : 
    2301              :   return changed;
    2302              : }
    2303              : 
    2304              : /* Search the successors of BB for common insn sequences.  When found,
    2305              :    share code between them by moving it across the basic block
    2306              :    boundary.  Return true if any changes made.  */
    2307              : 
    2308              : static bool
    2309     30141282 : try_head_merge_bb (basic_block bb)
    2310              : {
    2311     30141282 :   basic_block final_dest_bb = NULL;
    2312     30141282 :   int max_match = INT_MAX;
    2313     30141282 :   edge e0;
    2314     30141282 :   rtx_insn **headptr, **currptr, **nextptr;
    2315     30141282 :   bool changed, moveall;
    2316     30141282 :   unsigned ix;
    2317     30141282 :   rtx_insn *e0_last_head;
    2318     30141282 :   rtx cond;
    2319     30141282 :   rtx_insn *move_before;
    2320     30141282 :   unsigned nedges = EDGE_COUNT (bb->succs);
    2321     30141282 :   rtx_insn *jump = BB_END (bb);
    2322     30141282 :   regset live, live_union;
    2323              : 
    2324              :   /* Nothing to do if there is not at least two outgoing edges.  */
    2325     30141282 :   if (nedges < 2)
    2326              :     return false;
    2327              : 
    2328              :   /* Don't crossjump if this block ends in a computed jump,
    2329              :      unless we are optimizing for size.  */
    2330     15469646 :   if (optimize_bb_for_size_p (bb)
    2331      1818827 :       && bb != EXIT_BLOCK_PTR_FOR_FN (cfun)
    2332     17288473 :       && computed_jump_p (BB_END (bb)))
    2333              :     return false;
    2334              : 
    2335     15469598 :   cond = get_condition (jump, &move_before, true, false);
    2336     15469598 :   if (cond == NULL_RTX)
    2337      2203929 :     move_before = jump;
    2338              : 
    2339     46727930 :   for (ix = 0; ix < nedges; ix++)
    2340     31258332 :     if (EDGE_SUCC (bb, ix)->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
    2341              :       return false;
    2342              : 
    2343     28792572 :   for (ix = 0; ix < nedges; ix++)
    2344              :     {
    2345     24100757 :       edge e = EDGE_SUCC (bb, ix);
    2346     24100757 :       basic_block other_bb = e->dest;
    2347              : 
    2348     24100757 :       if (df_get_bb_dirty (other_bb))
    2349              :         {
    2350       559839 :           block_was_dirty = true;
    2351       559839 :           return false;
    2352              :         }
    2353              : 
    2354     23540918 :       if (e->flags & EDGE_ABNORMAL)
    2355              :         return false;
    2356              : 
    2357              :       /* Normally, all destination blocks must only be reachable from this
    2358              :          block, i.e. they must have one incoming edge.
    2359              : 
    2360              :          There is one special case we can handle, that of multiple consecutive
    2361              :          jumps where the first jumps to one of the targets of the second jump.
    2362              :          This happens frequently in switch statements for default labels.
    2363              :          The structure is as follows:
    2364              :          FINAL_DEST_BB
    2365              :          ....
    2366              :          if (cond) jump A;
    2367              :          fall through
    2368              :          BB
    2369              :          jump with targets A, B, C, D...
    2370              :          A
    2371              :          has two incoming edges, from FINAL_DEST_BB and BB
    2372              : 
    2373              :          In this case, we can try to move the insns through BB and into
    2374              :          FINAL_DEST_BB.  */
    2375     21419733 :       if (EDGE_COUNT (other_bb->preds) != 1)
    2376              :         {
    2377      8471109 :           edge incoming_edge, incoming_bb_other_edge;
    2378      8471109 :           edge_iterator ei;
    2379              : 
    2380      8471109 :           if (final_dest_bb != NULL
    2381      8471109 :               || EDGE_COUNT (other_bb->preds) != 2)
    2382      8096759 :             return false;
    2383              : 
    2384              :           /* We must be able to move the insns across the whole block.  */
    2385      4688399 :           move_before = BB_HEAD (bb);
    2386     31476337 :           while (!NONDEBUG_INSN_P (move_before))
    2387     26787938 :             move_before = NEXT_INSN (move_before);
    2388              : 
    2389      4688399 :           if (EDGE_COUNT (bb->preds) != 1)
    2390              :             return false;
    2391      2828330 :           incoming_edge = EDGE_PRED (bb, 0);
    2392      2828330 :           final_dest_bb = incoming_edge->src;
    2393     10433524 :           if (EDGE_COUNT (final_dest_bb->succs) != 2)
    2394              :             return false;
    2395      3366098 :           FOR_EACH_EDGE (incoming_bb_other_edge, ei, final_dest_bb->succs)
    2396      3366098 :             if (incoming_bb_other_edge != incoming_edge)
    2397              :               break;
    2398      2336765 :           if (incoming_bb_other_edge->dest != other_bb)
    2399              :             return false;
    2400              :         }
    2401              :     }
    2402              : 
    2403      4691815 :   e0 = EDGE_SUCC (bb, 0);
    2404      4691815 :   e0_last_head = NULL;
    2405      4691815 :   changed = false;
    2406              : 
    2407      4816866 :   for (ix = 1; ix < nedges; ix++)
    2408              :     {
    2409      4696632 :       edge e = EDGE_SUCC (bb, ix);
    2410      4696632 :       rtx_insn *e0_last, *e_last;
    2411      4696632 :       int nmatch;
    2412              : 
    2413      4696632 :       nmatch = flow_find_head_matching_sequence (e0->dest, e->dest,
    2414              :                                                  &e0_last, &e_last, 0);
    2415      4696632 :       if (nmatch == 0)
    2416      4571581 :         return false;
    2417              : 
    2418       125051 :       if (nmatch < max_match)
    2419              :         {
    2420       121207 :           max_match = nmatch;
    2421       121207 :           e0_last_head = e0_last;
    2422              :         }
    2423              :     }
    2424              : 
    2425              :   /* If we matched an entire block, we probably have to avoid moving the
    2426              :      last insn.  */
    2427       120234 :   if (max_match > 0
    2428       120234 :       && e0_last_head == BB_END (e0->dest)
    2429       129404 :       && (find_reg_note (e0_last_head, REG_EH_REGION, 0)
    2430         7595 :           || control_flow_insn_p (e0_last_head)))
    2431              :     {
    2432         1588 :       max_match--;
    2433         1588 :       if (max_match == 0)
    2434              :         return false;
    2435          273 :       e0_last_head = prev_real_nondebug_insn (e0_last_head);
    2436              :     }
    2437              : 
    2438       118919 :   if (max_match == 0)
    2439              :     return false;
    2440              : 
    2441              :   /* We must find a union of the live registers at each of the end points.  */
    2442       118919 :   live = BITMAP_ALLOC (NULL);
    2443       118919 :   live_union = BITMAP_ALLOC (NULL);
    2444              : 
    2445       118919 :   currptr = XNEWVEC (rtx_insn *, nedges);
    2446       118919 :   headptr = XNEWVEC (rtx_insn *, nedges);
    2447       118919 :   nextptr = XNEWVEC (rtx_insn *, nedges);
    2448              : 
    2449       479025 :   for (ix = 0; ix < nedges; ix++)
    2450              :     {
    2451       241187 :       int j;
    2452       241187 :       basic_block merge_bb = EDGE_SUCC (bb, ix)->dest;
    2453       241187 :       rtx_insn *head = BB_HEAD (merge_bb);
    2454              : 
    2455      1633706 :       while (!NONDEBUG_INSN_P (head))
    2456      1392519 :         head = NEXT_INSN (head);
    2457       241187 :       headptr[ix] = head;
    2458       241187 :       currptr[ix] = head;
    2459              : 
    2460              :       /* Compute the end point and live information  */
    2461       383634 :       for (j = 1; j < max_match; j++)
    2462       205456 :         do
    2463       205456 :           head = NEXT_INSN (head);
    2464       205456 :         while (!NONDEBUG_INSN_P (head));
    2465       241187 :       simulate_backwards_to_point (merge_bb, live, head);
    2466       241187 :       IOR_REG_SET (live_union, live);
    2467              :     }
    2468              : 
    2469              :   /* If we're moving across two blocks, verify the validity of the
    2470              :      first move, then adjust the target and let the loop below deal
    2471              :      with the final move.  */
    2472       118919 :   if (final_dest_bb != NULL)
    2473              :     {
    2474         7880 :       rtx_insn *move_upto;
    2475              : 
    2476         7880 :       moveall = can_move_insns_across (currptr[0], e0_last_head, move_before,
    2477              :                                        jump, e0->dest, live_union,
    2478              :                                        NULL, &move_upto);
    2479         7880 :       if (!moveall)
    2480              :         {
    2481         6215 :           if (move_upto == NULL_RTX)
    2482         5817 :             goto out;
    2483              : 
    2484         1217 :           while (e0_last_head != move_upto)
    2485              :             {
    2486          819 :               df_simulate_one_insn_backwards (e0->dest, e0_last_head,
    2487              :                                               live_union);
    2488          819 :               e0_last_head = PREV_INSN (e0_last_head);
    2489              :             }
    2490              :         }
    2491         2063 :       if (e0_last_head == NULL_RTX)
    2492            0 :         goto out;
    2493              : 
    2494         2063 :       jump = BB_END (final_dest_bb);
    2495         2063 :       cond = get_condition (jump, &move_before, true, false);
    2496         2063 :       if (cond == NULL_RTX)
    2497            0 :         move_before = jump;
    2498              :     }
    2499              : 
    2500       195255 :   do
    2501              :     {
    2502       195255 :       rtx_insn *move_upto;
    2503       195255 :       moveall = can_move_insns_across (currptr[0], e0_last_head,
    2504              :                                        move_before, jump, e0->dest, live_union,
    2505              :                                        NULL, &move_upto);
    2506       195255 :       if (!moveall && move_upto == NULL_RTX)
    2507              :         {
    2508       154976 :           if (jump == move_before)
    2509              :             break;
    2510              : 
    2511              :           /* Try again, using a different insertion point.  */
    2512        78133 :           move_before = jump;
    2513              : 
    2514        78133 :           continue;
    2515              :         }
    2516              : 
    2517        40279 :       if (final_dest_bb && !moveall)
    2518              :         /* We haven't checked whether a partial move would be OK for the first
    2519              :            move, so we have to fail this case.  */
    2520              :         break;
    2521              : 
    2522        57299 :       changed = true;
    2523        57299 :       for (;;)
    2524              :         {
    2525        57299 :           if (currptr[0] == move_upto)
    2526              :             break;
    2527        51245 :           for (ix = 0; ix < nedges; ix++)
    2528              :             {
    2529        34185 :               rtx_insn *curr = currptr[ix];
    2530        54164 :               do
    2531        54164 :                 curr = NEXT_INSN (curr);
    2532        54164 :               while (!NONDEBUG_INSN_P (curr));
    2533        34185 :               currptr[ix] = curr;
    2534              :             }
    2535              :         }
    2536              : 
    2537              :       /* If we can't currently move all of the identical insns, remember
    2538              :          each insn after the range that we'll merge.  */
    2539        40239 :       if (!moveall)
    2540        17445 :         for (ix = 0; ix < nedges; ix++)
    2541              :           {
    2542        11635 :             rtx_insn *curr = currptr[ix];
    2543        16481 :             do
    2544        16481 :               curr = NEXT_INSN (curr);
    2545        16481 :             while (!NONDEBUG_INSN_P (curr));
    2546        11635 :             nextptr[ix] = curr;
    2547              :           }
    2548              : 
    2549        40239 :       reorder_insns (headptr[0], currptr[0], PREV_INSN (move_before));
    2550        40239 :       df_set_bb_dirty (EDGE_SUCC (bb, 0)->dest);
    2551        40239 :       if (final_dest_bb != NULL)
    2552         2020 :         df_set_bb_dirty (final_dest_bb);
    2553        40239 :       df_set_bb_dirty (bb);
    2554       121989 :       for (ix = 1; ix < nedges; ix++)
    2555              :         {
    2556        41511 :           df_set_bb_dirty (EDGE_SUCC (bb, ix)->dest);
    2557        41511 :           delete_insn_chain (headptr[ix], currptr[ix], false);
    2558              :         }
    2559        40239 :       if (!moveall)
    2560              :         {
    2561         5810 :           if (jump == move_before)
    2562              :             break;
    2563              : 
    2564              :           /* For the unmerged insns, try a different insertion point.  */
    2565         4020 :           move_before = jump;
    2566              : 
    2567        12060 :           for (ix = 0; ix < nedges; ix++)
    2568         8040 :             currptr[ix] = headptr[ix] = nextptr[ix];
    2569              :         }
    2570              :     }
    2571       116582 :   while (!moveall);
    2572              : 
    2573        34429 :  out:
    2574       118919 :   free (currptr);
    2575       118919 :   free (headptr);
    2576       118919 :   free (nextptr);
    2577              : 
    2578       118919 :   crossjumps_occurred |= changed;
    2579              : 
    2580       118919 :   return changed;
    2581              : }
    2582              : 
    2583              : /* Return true if BB contains just bb note, or bb note followed
    2584              :    by only DEBUG_INSNs.  */
    2585              : 
    2586              : static bool
    2587     16737144 : trivially_empty_bb_p (basic_block bb)
    2588              : {
    2589     16737144 :   rtx_insn *insn = BB_END (bb);
    2590              : 
    2591         5598 :   while (1)
    2592              :     {
    2593     16742742 :       if (insn == BB_HEAD (bb))
    2594              :         return true;
    2595     16741785 :       if (!DEBUG_INSN_P (insn))
    2596              :         return false;
    2597         5598 :       insn = PREV_INSN (insn);
    2598              :     }
    2599              : }
    2600              : 
    2601              : /* Return true if BB contains just a return and possibly a USE of the
    2602              :    return value.  Fill in *RET and *USE with the return and use insns
    2603              :    if any found, otherwise NULL.  All CLOBBERs are ignored.  */
    2604              : 
    2605              : bool
    2606    412836118 : bb_is_just_return (basic_block bb, rtx_insn **ret, rtx_insn **use)
    2607              : {
    2608    412836118 :   *ret = *use = NULL;
    2609    412836118 :   rtx_insn *insn;
    2610              : 
    2611    412836118 :   if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
    2612              :     return false;
    2613              : 
    2614    554502515 :   FOR_BB_INSNS_REVERSE (bb, insn)
    2615    540710783 :     if (NONDEBUG_INSN_P (insn))
    2616              :       {
    2617    408050165 :         rtx pat = PATTERN (insn);
    2618              : 
    2619    408050165 :         if (!*ret && ANY_RETURN_P (pat))
    2620      7549504 :           *ret = insn;
    2621      7893500 :         else if (*ret && !*use && GET_CODE (pat) == USE
    2622      1141623 :             && REG_P (XEXP (pat, 0))
    2623    401642284 :             && REG_FUNCTION_VALUE_P (XEXP (pat, 0)))
    2624      1138337 :           *use = insn;
    2625    399362324 :         else if (GET_CODE (pat) != CLOBBER)
    2626              :           return false;
    2627              :       }
    2628              : 
    2629     13791732 :   return !!*ret;
    2630              : }
    2631              : 
    2632              : /* Do simple CFG optimizations - basic block merging, simplifying of jump
    2633              :    instructions etc.  Return nonzero if changes were made.  */
    2634              : 
    2635              : static bool
    2636     22345486 : try_optimize_cfg (int mode)
    2637              : {
    2638     22345486 :   bool changed_overall = false;
    2639     22345486 :   bool changed;
    2640     22345486 :   int iterations = 0;
    2641     22345486 :   basic_block bb, b, next;
    2642              : 
    2643     22345486 :   if (mode & (CLEANUP_CROSSJUMP | CLEANUP_THREADING))
    2644      3058271 :     clear_bb_flags ();
    2645              : 
    2646     22345486 :   crossjumps_occurred = false;
    2647              : 
    2648    327809089 :   FOR_EACH_BB_FN (bb, cfun)
    2649    305463603 :     update_forwarder_flag (bb);
    2650              : 
    2651     22345486 :   if (! targetm.cannot_modify_jumps_p ())
    2652              :     {
    2653     22345486 :       first_pass = true;
    2654              :       /* Attempt to merge blocks as made possible by edge removal.  If
    2655              :          a block has only one successor, and the successor has only
    2656              :          one predecessor, they may be combined.  */
    2657     52487326 :       do
    2658              :         {
    2659     26243663 :           block_was_dirty = false;
    2660     26243663 :           changed = false;
    2661     26243663 :           iterations++;
    2662              : 
    2663     26243663 :           if (dump_file)
    2664         1863 :             fprintf (dump_file,
    2665              :                      "\n\ntry_optimize_cfg iteration %i\n\n",
    2666              :                      iterations);
    2667              : 
    2668     26243663 :           for (b = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; b
    2669    443279922 :                != EXIT_BLOCK_PTR_FOR_FN (cfun);)
    2670              :             {
    2671    417036259 :               basic_block c;
    2672    417036259 :               edge s;
    2673    417036259 :               bool changed_here = false;
    2674              : 
    2675              :               /* Delete trivially dead basic blocks.  This is either
    2676              :                  blocks with no predecessors, or empty blocks with no
    2677              :                  successors.  However if the empty block with no
    2678              :                  successors is the successor of the ENTRY_BLOCK, it is
    2679              :                  kept.  This ensures that the ENTRY_BLOCK will have a
    2680              :                  successor which is a precondition for many RTL
    2681              :                  passes.  Empty blocks may result from expanding
    2682              :                  __builtin_unreachable ().  */
    2683    417036259 :               if (EDGE_COUNT (b->preds) == 0
    2684    417036259 :                   || (EDGE_COUNT (b->succs) == 0
    2685     16737144 :                       && trivially_empty_bb_p (b)
    2686          957 :                       && single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))->dest
    2687              :                       != b))
    2688              :                 {
    2689      5705759 :                   c = b->prev_bb;
    2690      5705759 :                   if (EDGE_COUNT (b->preds) > 0)
    2691              :                     {
    2692          957 :                       edge e;
    2693          957 :                       edge_iterator ei;
    2694              : 
    2695          957 :                       if (current_ir_type () == IR_RTL_CFGLAYOUT)
    2696              :                         {
    2697           51 :                           rtx_insn *insn;
    2698           51 :                           for (insn = BB_FOOTER (b);
    2699           51 :                                insn; insn = NEXT_INSN (insn))
    2700           51 :                             if (BARRIER_P (insn))
    2701              :                               break;
    2702           51 :                           if (insn)
    2703          102 :                             FOR_EACH_EDGE (e, ei, b->preds)
    2704           51 :                               if ((e->flags & EDGE_FALLTHRU))
    2705              :                                 {
    2706           51 :                                   if (BB_FOOTER (b)
    2707           51 :                                       && BB_FOOTER (e->src) == NULL)
    2708              :                                     {
    2709           51 :                                       BB_FOOTER (e->src) = BB_FOOTER (b);
    2710           51 :                                       BB_FOOTER (b) = NULL;
    2711              :                                     }
    2712              :                                   else
    2713            0 :                                     emit_barrier_after_bb (e->src);
    2714              :                                 }
    2715              :                         }
    2716              :                       else
    2717              :                         {
    2718          906 :                           rtx_insn *last = get_last_bb_insn (b);
    2719          906 :                           if (last && BARRIER_P (last))
    2720         1812 :                             FOR_EACH_EDGE (e, ei, b->preds)
    2721          906 :                               if ((e->flags & EDGE_FALLTHRU))
    2722          906 :                                 emit_barrier_after (BB_END (e->src));
    2723              :                         }
    2724              :                     }
    2725      5705759 :                   delete_basic_block (b);
    2726      5705759 :                   changed = true;
    2727              :                   /* Avoid trying to remove the exit block.  */
    2728      5705759 :                   b = (c == ENTRY_BLOCK_PTR_FOR_FN (cfun) ? c->next_bb : c);
    2729      5843465 :                   continue;
    2730      5705759 :                 }
    2731              : 
    2732              :               /* Remove code labels no longer used.  */
    2733    411330500 :               if (single_pred_p (b)
    2734    299194667 :                   && (single_pred_edge (b)->flags & EDGE_FALLTHRU)
    2735    210622154 :                   && !(single_pred_edge (b)->flags & EDGE_COMPLEX)
    2736    207229780 :                   && LABEL_P (BB_HEAD (b))
    2737       853282 :                   && !LABEL_PRESERVE_P (BB_HEAD (b))
    2738              :                   /* If the previous block ends with a branch to this
    2739              :                      block, we can't delete the label.  Normally this
    2740              :                      is a condjump that is yet to be simplified, but
    2741              :                      if CASE_DROPS_THRU, this can be a tablejump with
    2742              :                      some element going to the same place as the
    2743              :                      default (fallthru).  */
    2744    412168510 :                   && (single_pred (b) == ENTRY_BLOCK_PTR_FOR_FN (cfun)
    2745       837958 :                       || !JUMP_P (BB_END (single_pred (b)))
    2746       638929 :                       || ! label_is_jump_target_p (BB_HEAD (b),
    2747       638929 :                                                    BB_END (single_pred (b)))))
    2748              :                 {
    2749       831533 :                   delete_insn (BB_HEAD (b));
    2750       831533 :                   if (dump_file)
    2751           37 :                     fprintf (dump_file, "Deleted label in block %i.\n",
    2752              :                              b->index);
    2753              :                 }
    2754              : 
    2755              :               /* If we fall through an empty block, we can remove it.  */
    2756    411468206 :               if (!(mode & (CLEANUP_CFGLAYOUT | CLEANUP_NO_INSN_DEL))
    2757     87689662 :                   && single_pred_p (b)
    2758     64875293 :                   && (single_pred_edge (b)->flags & EDGE_FALLTHRU)
    2759     45878867 :                   && !LABEL_P (BB_HEAD (b))
    2760     45454697 :                   && FORWARDER_BLOCK_P (b)
    2761              :                   /* Note that forwarder_block_p true ensures that
    2762              :                      there is a successor for this block.  */
    2763      5403410 :                   && (single_succ_edge (b)->flags & EDGE_FALLTHRU)
    2764    411555090 :                   && n_basic_blocks_for_fn (cfun) > NUM_FIXED_BLOCKS + 1)
    2765              :                 {
    2766       137706 :                   if (dump_file)
    2767           11 :                     fprintf (dump_file,
    2768              :                              "Deleting fallthru block %i.\n",
    2769              :                              b->index);
    2770              : 
    2771         2623 :                   c = ((b->prev_bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
    2772       137706 :                        ? b->next_bb : b->prev_bb);
    2773       137706 :                   redirect_edge_succ_nodup (single_pred_edge (b),
    2774              :                                             single_succ (b));
    2775       137706 :                   delete_basic_block (b);
    2776       137706 :                   changed = true;
    2777       137706 :                   b = c;
    2778       137706 :                   continue;
    2779              :                 }
    2780              : 
    2781              :               /* Merge B with its single successor, if any.  */
    2782    820670139 :               if (single_succ_p (b)
    2783    180121607 :                   && (s = single_succ_edge (b))
    2784    180121607 :                   && !(s->flags & EDGE_COMPLEX)
    2785    170549959 :                   && (c = s->dest) != EXIT_BLOCK_PTR_FOR_FN (cfun)
    2786    144265468 :                   && single_pred_p (c)
    2787    418431328 :                   && b != c)
    2788              :                 {
    2789              :                   /* When not in cfg_layout mode use code aware of reordering
    2790              :                      INSN.  This code possibly creates new basic blocks so it
    2791              :                      does not fit merge_blocks interface and is kept here in
    2792              :                      hope that it will become useless once more of compiler
    2793              :                      is transformed to use cfg_layout mode.  */
    2794              : 
    2795      8953983 :                   if ((mode & CLEANUP_CFGLAYOUT)
    2796      8953983 :                       && can_merge_blocks_p (b, c))
    2797              :                     {
    2798       734739 :                       merge_blocks (b, c);
    2799       734739 :                       update_forwarder_flag (b);
    2800       734739 :                       changed_here = true;
    2801              :                     }
    2802      8219244 :                   else if (!(mode & CLEANUP_CFGLAYOUT)
    2803              :                            /* If the jump insn has side effects,
    2804              :                               we can't kill the edge.  */
    2805      6988650 :                            && (!JUMP_P (BB_END (b))
    2806      2284171 :                                || (reload_completed
    2807      3142059 :                                    ? simplejump_p (BB_END (b))
    2808       857888 :                                    : (onlyjump_p (BB_END (b))
    2809       857071 :                                       && !tablejump_p (BB_END (b),
    2810              :                                                        NULL, NULL))))
    2811     18347971 :                            && (next = merge_blocks_move (s, b, c, mode)))
    2812              :                       {
    2813              :                         b = next;
    2814              :                         changed_here = true;
    2815              :                       }
    2816              :                 }
    2817              : 
    2818              :               /* Try to change a branch to a return to just that return.  */
    2819    411192794 :               rtx_insn *ret, *use;
    2820    411192794 :               if (single_succ_p (b)
    2821    178463526 :                   && onlyjump_p (BB_END (b))
    2822    439352496 :                   && bb_is_just_return (single_succ (b), &ret, &use))
    2823              :                 {
    2824        37349 :                   if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)),
    2825        37349 :                                      PATTERN (ret), 0))
    2826              :                     {
    2827        37349 :                       if (use)
    2828        22057 :                         emit_insn_before (copy_insn (PATTERN (use)),
    2829        22057 :                                           BB_END (b));
    2830        37349 :                       if (dump_file)
    2831           23 :                         fprintf (dump_file, "Changed jump %d->%d to return.\n",
    2832           23 :                                  b->index, single_succ (b)->index);
    2833        37349 :                       redirect_edge_succ (single_succ_edge (b),
    2834        37349 :                                           EXIT_BLOCK_PTR_FOR_FN (cfun));
    2835        37349 :                       single_succ_edge (b)->flags &= ~EDGE_CROSSING;
    2836        37349 :                       changed_here = true;
    2837              :                     }
    2838              :                 }
    2839              : 
    2840              :               /* Try to change a conditional branch to a return to the
    2841              :                  respective conditional return.  */
    2842    411192794 :               if (EDGE_COUNT (b->succs) == 2
    2843    215522775 :                   && any_condjump_p (BB_END (b))
    2844    598744343 :                   && bb_is_just_return (BRANCH_EDGE (b)->dest, &ret, &use))
    2845              :                 {
    2846       601490 :                   if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)),
    2847       601490 :                                      PATTERN (ret), 0))
    2848              :                     {
    2849            0 :                       if (use)
    2850            0 :                         emit_insn_before (copy_insn (PATTERN (use)),
    2851            0 :                                           BB_END (b));
    2852            0 :                       if (dump_file)
    2853            0 :                         fprintf (dump_file, "Changed conditional jump %d->%d "
    2854              :                                  "to conditional return.\n",
    2855            0 :                                  b->index, BRANCH_EDGE (b)->dest->index);
    2856            0 :                       redirect_edge_succ (BRANCH_EDGE (b),
    2857            0 :                                           EXIT_BLOCK_PTR_FOR_FN (cfun));
    2858            0 :                       BRANCH_EDGE (b)->flags &= ~EDGE_CROSSING;
    2859            0 :                       changed_here = true;
    2860              :                     }
    2861              :                 }
    2862              : 
    2863              :               /* Try to flip a conditional branch that falls through to
    2864              :                  a return so that it becomes a conditional return and a
    2865              :                  new jump to the original branch target.  */
    2866    411192794 :               if (EDGE_COUNT (b->succs) == 2
    2867    215522775 :                   && BRANCH_EDGE (b)->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
    2868    215522775 :                   && any_condjump_p (BB_END (b))
    2869    598744343 :                   && bb_is_just_return (FALLTHRU_EDGE (b)->dest, &ret, &use))
    2870              :                 {
    2871       163364 :                   if (invert_jump (as_a <rtx_jump_insn *> (BB_END (b)),
    2872       163364 :                                    JUMP_LABEL (BB_END (b)), 0))
    2873              :                     {
    2874       163364 :                       basic_block new_ft = BRANCH_EDGE (b)->dest;
    2875       163364 :                       if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)),
    2876       163364 :                                          PATTERN (ret), 0))
    2877              :                         {
    2878            0 :                           if (use)
    2879            0 :                             emit_insn_before (copy_insn (PATTERN (use)),
    2880            0 :                                               BB_END (b));
    2881            0 :                           if (dump_file)
    2882            0 :                             fprintf (dump_file, "Changed conditional jump "
    2883              :                                      "%d->%d to conditional return, adding "
    2884              :                                      "fall-through jump.\n",
    2885            0 :                                      b->index, BRANCH_EDGE (b)->dest->index);
    2886            0 :                           redirect_edge_succ (BRANCH_EDGE (b),
    2887            0 :                                               EXIT_BLOCK_PTR_FOR_FN (cfun));
    2888            0 :                           BRANCH_EDGE (b)->flags &= ~EDGE_CROSSING;
    2889            0 :                           std::swap (BRANCH_EDGE (b)->probability,
    2890            0 :                                      FALLTHRU_EDGE (b)->probability);
    2891            0 :                           update_br_prob_note (b);
    2892            0 :                           basic_block jb = force_nonfallthru (FALLTHRU_EDGE (b));
    2893            0 :                           notice_new_block (jb);
    2894            0 :                           if (!redirect_jump (as_a <rtx_jump_insn *> (BB_END (jb)),
    2895            0 :                                               block_label (new_ft), 0))
    2896            0 :                             gcc_unreachable ();
    2897            0 :                           redirect_edge_succ (single_succ_edge (jb), new_ft);
    2898            0 :                           changed_here = true;
    2899              :                         }
    2900              :                       else
    2901              :                         {
    2902              :                           /* Invert the jump back to what it was.  This should
    2903              :                              never fail.  */
    2904       163364 :                           if (!invert_jump (as_a <rtx_jump_insn *> (BB_END (b)),
    2905       163364 :                                             JUMP_LABEL (BB_END (b)), 0))
    2906            0 :                             gcc_unreachable ();
    2907              :                         }
    2908              :                     }
    2909              :                 }
    2910              : 
    2911              :               /* Simplify branch over branch.  */
    2912    411192794 :               if ((mode & CLEANUP_EXPENSIVE)
    2913    108633738 :                    && !(mode & CLEANUP_CFGLAYOUT)
    2914    446571481 :                    && try_simplify_condjump (b))
    2915              :                 changed_here = true;
    2916              : 
    2917              :               /* If B has a single outgoing edge, but uses a
    2918              :                  non-trivial jump instruction without side-effects, we
    2919              :                  can either delete the jump entirely, or replace it
    2920              :                  with a simple unconditional jump.  */
    2921    411192794 :               if (single_succ_p (b)
    2922    178463586 :                   && single_succ (b) != EXIT_BLOCK_PTR_FOR_FN (cfun)
    2923    148067325 :                   && onlyjump_p (BB_END (b))
    2924     29905156 :                   && !CROSSING_JUMP_P (BB_END (b))
    2925    438112590 :                   && try_redirect_by_replacing_jump (single_succ_edge (b),
    2926              :                                                      single_succ (b),
    2927     28703205 :                                                      (mode & CLEANUP_CFGLAYOUT) != 0))
    2928              :                 {
    2929      4381479 :                   update_forwarder_flag (b);
    2930      4381479 :                   changed_here = true;
    2931              :                 }
    2932              : 
    2933              :               /* Simplify branch to branch.  */
    2934    411192794 :               if (try_forward_edges (mode, b))
    2935              :                 {
    2936      6592493 :                   update_forwarder_flag (b);
    2937      6592493 :                   changed_here = true;
    2938              :                 }
    2939              : 
    2940              :               /* Look for shared code between blocks.  */
    2941    411192794 :               if ((mode & CLEANUP_CROSSJUMP)
    2942    411192794 :                   && try_crossjump_bb (mode, b))
    2943              :                 changed_here = true;
    2944              : 
    2945    411192794 :               if ((mode & CLEANUP_CROSSJUMP)
    2946              :                   /* This can lengthen register lifetimes.  Do it only after
    2947              :                      reload.  */
    2948     30141282 :                   && reload_completed
    2949    441334076 :                   && try_head_merge_bb (b))
    2950              :                 changed_here = true;
    2951              : 
    2952              :               /* Don't get confused by the index shift caused by
    2953              :                  deleting blocks.  */
    2954    411153519 :               if (!changed_here)
    2955    396079175 :                 b = b->next_bb;
    2956              :               else
    2957              :                 changed = true;
    2958              :             }
    2959              : 
    2960     26243663 :           if ((mode & CLEANUP_CROSSJUMP)
    2961     26243663 :               && try_crossjump_bb (mode, EXIT_BLOCK_PTR_FOR_FN (cfun)))
    2962              :             changed = true;
    2963              : 
    2964     26243663 :           if (block_was_dirty)
    2965              :             {
    2966              :               /* This should only be set by head-merging.  */
    2967       200471 :               gcc_assert (mode & CLEANUP_CROSSJUMP);
    2968       200471 :               df_analyze ();
    2969              :             }
    2970              : 
    2971     26243663 :           if (changed)
    2972              :             {
    2973              :               /* Edge forwarding in particular can cause hot blocks previously
    2974              :                  reached by both hot and cold blocks to become dominated only
    2975              :                  by cold blocks. This will cause the verification below to fail,
    2976              :                  and lead to now cold code in the hot section. This is not easy
    2977              :                  to detect and fix during edge forwarding, and in some cases
    2978              :                  is only visible after newly unreachable blocks are deleted,
    2979              :                  which will be done in fixup_partitions.  */
    2980      3898177 :               if ((mode & CLEANUP_NO_PARTITIONING) == 0)
    2981              :                 {
    2982      3759878 :                   fixup_partitions ();
    2983      3759878 :                   checking_verify_flow_info ();
    2984              :                 }
    2985              :             }
    2986              : 
    2987     26243663 :           changed_overall |= changed;
    2988     26243663 :           first_pass = false;
    2989              :         }
    2990              :       while (changed);
    2991              :     }
    2992              : 
    2993    362121956 :   FOR_ALL_BB_FN (b, cfun)
    2994    339776470 :     b->flags &= ~(BB_FORWARDER_BLOCK | BB_NONTHREADABLE_BLOCK);
    2995              : 
    2996     22345486 :   return changed_overall;
    2997              : }
    2998              : 
    2999              : /* Delete all unreachable basic blocks.  */
    3000              : 
    3001              : bool
    3002     28842651 : delete_unreachable_blocks (void)
    3003              : {
    3004     28842651 :   bool changed = false;
    3005     28842651 :   basic_block b, prev_bb;
    3006              : 
    3007     28842651 :   find_unreachable_blocks ();
    3008              : 
    3009              :   /* When we're in GIMPLE mode and there may be debug bind insns, we
    3010              :      should delete blocks in reverse dominator order, so as to get a
    3011              :      chance to substitute all released DEFs into debug bind stmts.  If
    3012              :      we don't have dominators information, walking blocks backward
    3013              :      gets us a better chance of retaining most debug information than
    3014              :      otherwise.  */
    3015     13088817 :   if (MAY_HAVE_DEBUG_BIND_INSNS && current_ir_type () == IR_GIMPLE
    3016     29119820 :       && dom_info_available_p (CDI_DOMINATORS))
    3017              :     {
    3018            0 :       for (b = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
    3019            0 :            b != ENTRY_BLOCK_PTR_FOR_FN (cfun); b = prev_bb)
    3020              :         {
    3021            0 :           prev_bb = b->prev_bb;
    3022              : 
    3023            0 :           if (!(b->flags & BB_REACHABLE))
    3024              :             {
    3025              :               /* Speed up the removal of blocks that don't dominate
    3026              :                  others.  Walking backwards, this should be the common
    3027              :                  case.  */
    3028            0 :               if (!first_dom_son (CDI_DOMINATORS, b))
    3029            0 :                 delete_basic_block (b);
    3030              :               else
    3031              :                 {
    3032            0 :                   auto_vec<basic_block> h
    3033            0 :                     = get_all_dominated_blocks (CDI_DOMINATORS, b);
    3034              : 
    3035            0 :                   while (h.length ())
    3036              :                     {
    3037            0 :                       b = h.pop ();
    3038              : 
    3039            0 :                       prev_bb = b->prev_bb;
    3040              : 
    3041            0 :                       gcc_assert (!(b->flags & BB_REACHABLE));
    3042              : 
    3043            0 :                       delete_basic_block (b);
    3044              :                     }
    3045            0 :                 }
    3046              : 
    3047              :               changed = true;
    3048              :             }
    3049              :         }
    3050              :     }
    3051              :   else
    3052              :     {
    3053     28842651 :       for (b = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
    3054    430050377 :            b != ENTRY_BLOCK_PTR_FOR_FN (cfun); b = prev_bb)
    3055              :         {
    3056    401207726 :           prev_bb = b->prev_bb;
    3057              : 
    3058    401207726 :           if (!(b->flags & BB_REACHABLE))
    3059              :             {
    3060      1756330 :               delete_basic_block (b);
    3061      1756330 :               changed = true;
    3062              :             }
    3063              :         }
    3064              :     }
    3065              : 
    3066     28842651 :   if (changed)
    3067       469591 :     tidy_fallthru_edges ();
    3068     28842651 :   return changed;
    3069              : }
    3070              : 
    3071              : /* Delete any jump tables never referenced.  We can't delete them at the
    3072              :    time of removing tablejump insn as they are referenced by the preceding
    3073              :    insns computing the destination, so we delay deleting and garbagecollect
    3074              :    them once life information is computed.  */
    3075              : void
    3076      9354817 : delete_dead_jumptables (void)
    3077              : {
    3078      9354817 :   basic_block bb;
    3079              : 
    3080              :   /* A dead jump table does not belong to any basic block.  Scan insns
    3081              :      between two adjacent basic blocks.  */
    3082    104483572 :   FOR_EACH_BB_FN (bb, cfun)
    3083              :     {
    3084     95128755 :       rtx_insn *insn, *next;
    3085              : 
    3086     95128755 :       for (insn = NEXT_INSN (BB_END (bb));
    3087    174084372 :            insn && !NOTE_INSN_BASIC_BLOCK_P (insn);
    3088     78955617 :            insn = next)
    3089              :         {
    3090     78955617 :           next = NEXT_INSN (insn);
    3091     78955617 :           if (LABEL_P (insn)
    3092     44767079 :               && LABEL_NUSES (insn) == LABEL_PRESERVE_P (insn)
    3093     81029641 :               && JUMP_TABLE_DATA_P (next))
    3094              :             {
    3095            0 :               rtx_insn *label = insn, *jump = next;
    3096              : 
    3097            0 :               if (dump_file)
    3098            0 :                 fprintf (dump_file, "Dead jumptable %i removed\n",
    3099            0 :                          INSN_UID (insn));
    3100              : 
    3101            0 :               next = NEXT_INSN (next);
    3102            0 :               delete_insn (jump);
    3103            0 :               delete_insn (label);
    3104              :             }
    3105              :         }
    3106              :     }
    3107      9354817 : }
    3108              : 
    3109              : 
    3110              : /* Tidy the CFG by deleting unreachable code and whatnot.  */
    3111              : 
    3112              : bool
    3113     20139711 : cleanup_cfg (int mode)
    3114              : {
    3115     20139711 :   bool changed = false;
    3116              : 
    3117              :   /* Set the cfglayout mode flag here.  We could update all the callers
    3118              :      but that is just inconvenient, especially given that we eventually
    3119              :      want to have cfglayout mode as the default.  */
    3120     20139711 :   if (current_ir_type () == IR_RTL_CFGLAYOUT)
    3121     13371317 :     mode |= CLEANUP_CFGLAYOUT;
    3122              : 
    3123     20139711 :   timevar_push (TV_CLEANUP_CFG);
    3124     20139711 :   if (delete_unreachable_blocks ())
    3125              :     {
    3126       158985 :       changed = true;
    3127              :       /* We've possibly created trivially dead code.  Cleanup it right
    3128              :          now to introduce more opportunities for try_optimize_cfg.  */
    3129       158985 :       if (!(mode & (CLEANUP_NO_INSN_DEL))
    3130        42056 :           && !reload_completed)
    3131        41991 :         delete_trivially_dead_insns (get_insns (), max_reg_num ());
    3132              :     }
    3133              : 
    3134     20139711 :   compact_blocks ();
    3135              : 
    3136              :   /* To tail-merge blocks ending in the same noreturn function (e.g.
    3137              :      a call to abort) we have to insert fake edges to exit.  Do this
    3138              :      here once.  The fake edges do not interfere with any other CFG
    3139              :      cleanups.  */
    3140     20139711 :   if (mode & CLEANUP_CROSSJUMP)
    3141       988538 :     add_noreturn_fake_exit_edges ();
    3142              : 
    3143     20139711 :   if (!dbg_cnt (cfg_cleanup))
    3144              :     return changed;
    3145              : 
    3146     22345486 :   while (try_optimize_cfg (mode))
    3147              :     {
    3148      3805255 :       delete_unreachable_blocks (), changed = true;
    3149      3805255 :       if (!(mode & CLEANUP_NO_INSN_DEL))
    3150              :         {
    3151              :           /* Try to remove some trivially dead insns when doing an expensive
    3152              :              cleanup.  But delete_trivially_dead_insns doesn't work after
    3153              :              reload (it only handles pseudos) and run_fast_dce is too costly
    3154              :              to run in every iteration.
    3155              : 
    3156              :              For effective cross jumping, we really want to run a fast DCE to
    3157              :              clean up any dead conditions, or they get in the way of performing
    3158              :              useful tail merges.
    3159              : 
    3160              :              Other transformations in cleanup_cfg are not so sensitive to dead
    3161              :              code, so delete_trivially_dead_insns or even doing nothing at all
    3162              :              is good enough.  */
    3163       620250 :           if ((mode & CLEANUP_EXPENSIVE) && !reload_completed
    3164      2217095 :               && !delete_trivially_dead_insns (get_insns (), max_reg_num ()))
    3165              :             break;
    3166      2205775 :           if ((mode & CLEANUP_CROSSJUMP) && crossjumps_occurred)
    3167              :             {
    3168        83108 :               run_fast_dce ();
    3169        83108 :               mode &= ~CLEANUP_FORCE_FAST_DCE;
    3170              :             }
    3171              :         }
    3172              :       else
    3173              :         break;
    3174              :     }
    3175              : 
    3176     20139711 :   if (mode & CLEANUP_CROSSJUMP)
    3177       988538 :     remove_fake_exit_edges ();
    3178              : 
    3179     20139711 :   if (mode & CLEANUP_FORCE_FAST_DCE)
    3180       122029 :     run_fast_dce ();
    3181              : 
    3182              :   /* Don't call delete_dead_jumptables in cfglayout mode, because
    3183              :      that function assumes that jump tables are in the insns stream.
    3184              :      But we also don't _have_ to delete dead jumptables in cfglayout
    3185              :      mode because we shouldn't even be looking at things that are
    3186              :      not in a basic block.  Dead jumptables are cleaned up when
    3187              :      going out of cfglayout mode.  */
    3188     20139711 :   if (!(mode & CLEANUP_CFGLAYOUT))
    3189      6768394 :     delete_dead_jumptables ();
    3190              : 
    3191              :   /* ???  We probably do this way too often.  */
    3192     20139711 :   if (current_loops
    3193      9381227 :       && (changed
    3194      6954319 :           || (mode & CLEANUP_CFG_CHANGED)))
    3195              :     {
    3196      2522142 :       timevar_push (TV_REPAIR_LOOPS);
    3197              :       /* The above doesn't preserve dominance info if available.  */
    3198      2522142 :       gcc_assert (!dom_info_available_p (CDI_DOMINATORS));
    3199      2522142 :       calculate_dominance_info (CDI_DOMINATORS);
    3200      2522142 :       fix_loop_structure (NULL);
    3201      2522142 :       free_dominance_info (CDI_DOMINATORS);
    3202      2522142 :       timevar_pop (TV_REPAIR_LOOPS);
    3203              :     }
    3204              : 
    3205     20139711 :   timevar_pop (TV_CLEANUP_CFG);
    3206              : 
    3207     20139711 :   return changed;
    3208              : }
    3209              : 
    3210              : namespace {
    3211              : 
    3212              : const pass_data pass_data_jump =
    3213              : {
    3214              :   RTL_PASS, /* type */
    3215              :   "jump", /* name */
    3216              :   OPTGROUP_NONE, /* optinfo_flags */
    3217              :   TV_JUMP, /* tv_id */
    3218              :   0, /* properties_required */
    3219              :   0, /* properties_provided */
    3220              :   0, /* properties_destroyed */
    3221              :   0, /* todo_flags_start */
    3222              :   0, /* todo_flags_finish */
    3223              : };
    3224              : 
    3225              : class pass_jump : public rtl_opt_pass
    3226              : {
    3227              : public:
    3228       294536 :   pass_jump (gcc::context *ctxt)
    3229       589072 :     : rtl_opt_pass (pass_data_jump, ctxt)
    3230              :   {}
    3231              : 
    3232              :   /* opt_pass methods: */
    3233              :   unsigned int execute (function *) final override;
    3234              : 
    3235              : }; // class pass_jump
    3236              : 
    3237              : unsigned int
    3238      1515918 : pass_jump::execute (function *)
    3239              : {
    3240      1515918 :   delete_trivially_dead_insns (get_insns (), max_reg_num ());
    3241      1515918 :   if (dump_file)
    3242           84 :     dump_flow_info (dump_file, dump_flags);
    3243      3031836 :   cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0)
    3244      1070056 :                | (flag_thread_jumps && flag_expensive_optimizations
    3245      1515918 :                   ? CLEANUP_THREADING : 0));
    3246      1515918 :   return 0;
    3247              : }
    3248              : 
    3249              : } // anon namespace
    3250              : 
    3251              : rtl_opt_pass *
    3252       294536 : make_pass_jump (gcc::context *ctxt)
    3253              : {
    3254       294536 :   return new pass_jump (ctxt);
    3255              : }
    3256              : 
    3257              : namespace {
    3258              : 
    3259              : const pass_data pass_data_jump_after_combine =
    3260              : {
    3261              :   RTL_PASS, /* type */
    3262              :   "jump_after_combine", /* name */
    3263              :   OPTGROUP_NONE, /* optinfo_flags */
    3264              :   TV_JUMP, /* tv_id */
    3265              :   0, /* properties_required */
    3266              :   0, /* properties_provided */
    3267              :   0, /* properties_destroyed */
    3268              :   0, /* todo_flags_start */
    3269              :   0, /* todo_flags_finish */
    3270              : };
    3271              : 
    3272              : class pass_jump_after_combine : public rtl_opt_pass
    3273              : {
    3274              : public:
    3275       294536 :   pass_jump_after_combine (gcc::context *ctxt)
    3276       589072 :     : rtl_opt_pass (pass_data_jump_after_combine, ctxt)
    3277              :   {}
    3278              : 
    3279              :   /* opt_pass methods: */
    3280      1515929 :   bool gate (function *) final override
    3281              :   {
    3282      1515929 :     return flag_thread_jumps && flag_expensive_optimizations;
    3283              :   }
    3284              :   unsigned int execute (function *) final override;
    3285              : 
    3286              : }; // class pass_jump_after_combine
    3287              : 
    3288              : unsigned int
    3289       988377 : pass_jump_after_combine::execute (function *)
    3290              : {
    3291              :   /* Jump threading does not keep dominators up-to-date.  */
    3292       988377 :   free_dominance_info (CDI_DOMINATORS);
    3293       988377 :   cleanup_cfg (CLEANUP_THREADING);
    3294       988377 :   return 0;
    3295              : }
    3296              : 
    3297              : } // anon namespace
    3298              : 
    3299              : rtl_opt_pass *
    3300       294536 : make_pass_jump_after_combine (gcc::context *ctxt)
    3301              : {
    3302       294536 :   return new pass_jump_after_combine (ctxt);
    3303              : }
    3304              : 
    3305              : namespace {
    3306              : 
    3307              : const pass_data pass_data_jump2 =
    3308              : {
    3309              :   RTL_PASS, /* type */
    3310              :   "jump2", /* name */
    3311              :   OPTGROUP_NONE, /* optinfo_flags */
    3312              :   TV_JUMP, /* tv_id */
    3313              :   0, /* properties_required */
    3314              :   0, /* properties_provided */
    3315              :   0, /* properties_destroyed */
    3316              :   0, /* todo_flags_start */
    3317              :   0, /* todo_flags_finish */
    3318              : };
    3319              : 
    3320              : class pass_jump2 : public rtl_opt_pass
    3321              : {
    3322              : public:
    3323       294536 :   pass_jump2 (gcc::context *ctxt)
    3324       589072 :     : rtl_opt_pass (pass_data_jump2, ctxt)
    3325              :   {}
    3326              : 
    3327              :   /* opt_pass methods: */
    3328      1515922 :   unsigned int execute (function *) final override
    3329              :     {
    3330      2043306 :       cleanup_cfg (flag_crossjumping ? CLEANUP_CROSSJUMP : 0);
    3331      1515922 :       return 0;
    3332              :     }
    3333              : 
    3334              : }; // class pass_jump2
    3335              : 
    3336              : } // anon namespace
    3337              : 
    3338              : rtl_opt_pass *
    3339       294536 : make_pass_jump2 (gcc::context *ctxt)
    3340              : {
    3341       294536 :   return new pass_jump2 (ctxt);
    3342              : }
        

Generated by: LCOV version 2.5.0-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.