LCOV - code coverage report
Current view: top level - gcc - cfgcleanup.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.2 % 1432 1334
Test Date: 2026-06-20 15:32:29 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        20417 : notice_new_block (basic_block bb)
      90              : {
      91        20417 :   if (!bb)
      92              :     return;
      93              : 
      94        14477 :   if (forwarder_block_p (bb))
      95        14477 :     bb->flags |= BB_FORWARDER_BLOCK;
      96              : }
      97              : 
      98              : /* Recompute forwarder flag after block has been modified.  */
      99              : 
     100              : static void
     101    307667226 : update_forwarder_flag (basic_block bb)
     102              : {
     103    307667226 :   if (forwarder_block_p (bb))
     104     16220047 :     bb->flags |= BB_FORWARDER_BLOCK;
     105              :   else
     106    291447179 :     bb->flags &= ~BB_FORWARDER_BLOCK;
     107    307667226 : }
     108              : 
     109              : /* Simplify a conditional jump around an unconditional jump.
     110              :    Return true if something changed.  */
     111              : 
     112              : static bool
     113     33581606 : try_simplify_condjump (basic_block cbranch_block)
     114              : {
     115     33581606 :   basic_block jump_block, jump_dest_block, cbranch_dest_block;
     116     33581606 :   edge cbranch_jump_edge, cbranch_fallthru_edge;
     117     33581606 :   rtx_insn *cbranch_insn;
     118              : 
     119              :   /* Verify that there are exactly two successors.  */
     120     33581606 :   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     16872281 :   cbranch_insn = BB_END (cbranch_block);
     126     16872281 :   if (!any_condjump_p (cbranch_insn))
     127              :     return false;
     128              : 
     129     14848764 :   cbranch_fallthru_edge = FALLTHRU_EDGE (cbranch_block);
     130     14848764 :   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     14848764 :   jump_block = cbranch_fallthru_edge->dest;
     136     48423318 :   if (!single_pred_p (jump_block)
     137     13220278 :       || jump_block->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
     138     27903925 :       || !FORWARDER_BLOCK_P (jump_block))
     139              :     return false;
     140      1677020 :   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      1677020 :   if (BB_PARTITION (jump_block) != BB_PARTITION (jump_dest_block)
     153      1637195 :       || (cbranch_jump_edge->flags & EDGE_CROSSING))
     154              :     return false;
     155              : 
     156              :   /* The conditional branch must target the block after the
     157              :      unconditional branch.  */
     158      1407890 :   cbranch_dest_block = cbranch_jump_edge->dest;
     159              : 
     160      1407890 :   if (cbranch_dest_block == EXIT_BLOCK_PTR_FOR_FN (cfun)
     161      1407890 :       || jump_dest_block == EXIT_BLOCK_PTR_FOR_FN (cfun)
     162      2814975 :       || !can_fallthru (jump_block, cbranch_dest_block))
     163      1400838 :     return false;
     164              : 
     165              :   /* Invert the conditional branch.  */
     166         7052 :   if (!invert_jump (as_a <rtx_jump_insn *> (cbranch_insn),
     167         7052 :                     block_label (jump_dest_block), 0))
     168              :     return false;
     169              : 
     170         7052 :   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         7052 :   cbranch_jump_edge = redirect_edge_succ_nodup (cbranch_jump_edge,
     178              :                                                 cbranch_dest_block);
     179         7052 :   cbranch_fallthru_edge = redirect_edge_succ_nodup (cbranch_fallthru_edge,
     180              :                                                     jump_dest_block);
     181         7052 :   cbranch_jump_edge->flags |= EDGE_FALLTHRU;
     182         7052 :   cbranch_fallthru_edge->flags &= ~EDGE_FALLTHRU;
     183         7052 :   update_br_prob_note (cbranch_block);
     184              : 
     185              :   /* Delete the block with the unconditional jump, and clean up the mess.  */
     186         7052 :   delete_basic_block (jump_block);
     187         7052 :   tidy_fallthru_edge (cbranch_jump_edge);
     188         7052 :   update_forwarder_flag (cbranch_block);
     189              : 
     190         7052 :   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     31966277 : mark_effect (rtx exp, regset nonequal)
     198              : {
     199     31966277 :   rtx dest;
     200     31966277 :   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      2364638 :     case CLOBBER:
     205      2364638 :       dest = XEXP (exp, 0);
     206      2364638 :       if (REG_P (dest))
     207      2334421 :         bitmap_clear_range (nonequal, REGNO (dest), REG_NREGS (dest));
     208              :       return false;
     209              : 
     210     10791726 :     case SET:
     211     10791726 :       if (cselib_redundant_set_p (exp))
     212              :         return false;
     213     10609860 :       dest = SET_DEST (exp);
     214     10609860 :       if (dest == pc_rtx)
     215              :         return false;
     216     10602705 :       if (!REG_P (dest))
     217              :         return true;
     218     10044033 :       bitmap_set_range (nonequal, REGNO (dest), REG_NREGS (dest));
     219     10044033 :       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      3460015 : mentions_nonequal_regs (const_rtx x, regset nonequal)
     229              : {
     230      3460015 :   subrtx_iterator::array_type array;
     231      6935304 :   FOR_EACH_SUBRTX (iter, array, x, NONCONST)
     232              :     {
     233      6928149 :       const_rtx x = *iter;
     234      6928149 :       if (REG_P (x))
     235              :         {
     236      3460256 :           unsigned int end_regno = END_REGNO (x);
     237      3467652 :           for (unsigned int regno = REGNO (x); regno < end_regno; ++regno)
     238      3460256 :             if (REGNO_REG_SET_P (nonequal, regno))
     239      3452860 :               return true;
     240              :         }
     241              :     }
     242         7155 :   return false;
     243      3460015 : }
     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     27684713 : thread_jump (edge e, basic_block b)
     251              : {
     252     27684713 :   rtx set1, set2, cond1, cond2;
     253     27684713 :   rtx_insn *insn;
     254     27684713 :   enum rtx_code code1, code2, reversed_code2;
     255     27684713 :   bool reverse1 = false;
     256     27684713 :   unsigned i;
     257     27684713 :   regset nonequal;
     258     27684713 :   bool failed = false;
     259              : 
     260              :   /* Jump threading may cause fixup_partitions to introduce new crossing edges,
     261              :      which is not allowed after reload.  */
     262     27684713 :   gcc_checking_assert (!reload_completed || !crtl->has_bb_partition);
     263              : 
     264     27684713 :   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     44361676 :   if (EDGE_COUNT (e->src->succs) != 2)
     270              :     return NULL;
     271     16683521 :   if (EDGE_COUNT (b->succs) != 2)
     272              :     {
     273      7366429 :       b->flags |= BB_NONTHREADABLE_BLOCK;
     274      7366429 :       return NULL;
     275              :     }
     276              : 
     277              :   /* Second branch must end with onlyjump, as we will eliminate the jump.  */
     278      9317092 :   if (!any_condjump_p (BB_END (e->src)))
     279              :     return NULL;
     280              : 
     281      8514240 :   if (!any_condjump_p (BB_END (b)) || !onlyjump_p (BB_END (b)))
     282              :     {
     283       613076 :       b->flags |= BB_NONTHREADABLE_BLOCK;
     284       613076 :       return NULL;
     285              :     }
     286              : 
     287      7901164 :   set1 = pc_set (BB_END (e->src));
     288      7901164 :   set2 = pc_set (BB_END (b));
     289      7901164 :   if (((e->flags & EDGE_FALLTHRU) != 0)
     290      7901164 :       != (XEXP (SET_SRC (set1), 1) == pc_rtx))
     291      3883009 :     reverse1 = true;
     292              : 
     293      7901164 :   cond1 = XEXP (SET_SRC (set1), 0);
     294      7901164 :   cond2 = XEXP (SET_SRC (set2), 0);
     295      7901164 :   if (reverse1)
     296      3883009 :     code1 = reversed_comparison_code (cond1, BB_END (e->src));
     297              :   else
     298      4018155 :     code1 = GET_CODE (cond1);
     299              : 
     300      7901164 :   code2 = GET_CODE (cond2);
     301      7901164 :   reversed_code2 = reversed_comparison_code (cond2, BB_END (b));
     302              : 
     303      7901164 :   if (!comparison_dominates_p (code1, code2)
     304      7901164 :       && !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      6335331 :   if (!rtx_equal_p (XEXP (cond1, 0), XEXP (cond2, 0))
     312      6335331 :       || !rtx_equal_p (XEXP (cond1, 1), XEXP (cond2, 1)))
     313       909703 :     return NULL;
     314              : 
     315              :   /* Punt if BB_END (e->src) is doloop-like conditional jump that modifies
     316              :      the registers used in cond1.  */
     317      5425628 :   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     61877038 :   for (insn = NEXT_INSN (BB_HEAD (b)); insn != NEXT_INSN (BB_END (b));
     323     51025782 :        insn = NEXT_INSN (insn))
     324     52432723 :     if (INSN_P (insn) && side_effects_p (PATTERN (insn)))
     325              :       {
     326      1406941 :         b->flags |= BB_NONTHREADABLE_BLOCK;
     327      1406941 :         return NULL;
     328              :       }
     329              : 
     330      4018687 :   cselib_init (0);
     331              : 
     332              :   /* First process all values computed in the source basic block.  */
     333     56828912 :   for (insn = NEXT_INSN (BB_HEAD (e->src));
     334     56828912 :        insn != NEXT_INSN (BB_END (e->src));
     335     52810225 :        insn = NEXT_INSN (insn))
     336     52810225 :     if (INSN_P (insn))
     337     49170193 :       cselib_process_insn (insn);
     338              : 
     339      4018687 :   nonequal = BITMAP_ALLOC (NULL);
     340      4018687 :   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     36533624 :   for (insn = NEXT_INSN (BB_HEAD (b));
     347     36533624 :        insn != NEXT_INSN (BB_END (b)) && !failed;
     348     32514937 :        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     35967797 :       if (insn == BB_END (b)
     354     35967797 :           && mentions_nonequal_regs (cond2, nonequal))
     355      3452860 :         goto failed_exit;
     356              : 
     357     32514937 :       if (INSN_P (insn))
     358              :         {
     359     29509534 :           rtx pat = PATTERN (insn);
     360              : 
     361     29509534 :           if (GET_CODE (pat) == PARALLEL)
     362              :             {
     363      7207069 :               for (i = 0; i < (unsigned)XVECLEN (pat, 0); i++)
     364      4831906 :                 failed |= mark_effect (XVECEXP (pat, 0, i), nonequal);
     365              :             }
     366              :           else
     367     27134371 :             failed |= mark_effect (pat, nonequal);
     368              :         }
     369              : 
     370     32514937 :       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       565827 :   if (failed)
     376              :     {
     377       558672 :       b->flags |= BB_NONTHREADABLE_BLOCK;
     378       558672 :       goto failed_exit;
     379              :     }
     380              : 
     381         7155 :   if (!REG_SET_EMPTY_P (nonequal))
     382          597 :     goto failed_exit;
     383              : 
     384         6558 :   BITMAP_FREE (nonequal);
     385         6558 :   cselib_finish ();
     386         6558 :   if ((comparison_dominates_p (code1, code2) != 0)
     387         6558 :       != (XEXP (SET_SRC (set2), 1) == pc_rtx))
     388         4412 :     return BRANCH_EDGE (b);
     389              :   else
     390         2146 :     return FALLTHRU_EDGE (b);
     391              : 
     392      4012129 : failed_exit:
     393      4012129 :   BITMAP_FREE (nonequal);
     394      4012129 :   cselib_finish ();
     395      4012129 :   return NULL;
     396              : }
     397              : 
     398              : /* Attempt to forward edges leaving basic block B.
     399              :    Return true if successful.  */
     400              : 
     401              : static bool
     402    393660377 : try_forward_edges (int mode, basic_block b)
     403              : {
     404    393660377 :   bool changed = false;
     405    393660377 :   edge_iterator ei;
     406    393660377 :   edge e, *threaded_edges = NULL;
     407              : 
     408    986598214 :   for (ei = ei_start (b->succs); (e = ei_safe_edge (ei)); )
     409              :     {
     410    592937837 :       basic_block target, first;
     411    592937837 :       location_t goto_locus;
     412    592937837 :       int counter;
     413    592937837 :       bool threaded = false;
     414    592937837 :       int nthreaded_edges = 0;
     415    592937837 :       bool may_thread = first_pass || (b->flags & BB_MODIFIED) != 0;
     416    592937837 :       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    592937837 :       if (e->flags & EDGE_COMPLEX)
     424              :         {
     425     32526320 :           ei_next (&ei);
     426     32526320 :           continue;
     427              :         }
     428              : 
     429    560411517 :       target = first = e->dest;
     430    560411517 :       counter = NUM_FIXED_BLOCKS;
     431    560411517 :       goto_locus = e->goto_locus;
     432              : 
     433    590420672 :       while (counter < n_basic_blocks_for_fn (cfun))
     434              :         {
     435    590007389 :           basic_block new_target = NULL;
     436    590007389 :           may_thread |= (target->flags & BB_MODIFIED) != 0;
     437              : 
     438    590007389 :           if (FORWARDER_BLOCK_P (target)
     439    629339108 :               && single_succ (target) != EXIT_BLOCK_PTR_FOR_FN (cfun))
     440              :             {
     441              :               /* Bypass trivial infinite loops.  */
     442     30189969 :               new_target = single_succ (target);
     443     30189969 :               if (target == new_target)
     444              :                 counter = n_basic_blocks_for_fn (cfun);
     445     29914924 :               else if (!optimize)
     446              :                 {
     447              :                   /* When not optimizing, ensure that edges or forwarder
     448              :                      blocks with different locus are not optimized out.  */
     449      1185886 :                   location_t new_locus = single_succ_edge (target)->goto_locus;
     450      1185886 :                   location_t locus = goto_locus;
     451              : 
     452      1185886 :                   if (LOCATION_LOCUS (new_locus) != UNKNOWN_LOCATION
     453       469180 :                       && LOCATION_LOCUS (locus) != UNKNOWN_LOCATION
     454      1493896 :                       && new_locus != locus)
     455              :                     new_target = NULL;
     456              :                   else
     457              :                     {
     458      1007407 :                       if (LOCATION_LOCUS (new_locus) != UNKNOWN_LOCATION)
     459       290701 :                         locus = new_locus;
     460              : 
     461      1007407 :                       rtx_insn *last = BB_END (target);
     462      1007407 :                       if (DEBUG_INSN_P (last))
     463            6 :                         last = prev_nondebug_insn (last);
     464      1007407 :                       if (last && INSN_P (last))
     465       498113 :                         new_locus = INSN_LOCATION (last);
     466              :                       else
     467              :                         new_locus = UNKNOWN_LOCATION;
     468              : 
     469       498113 :                       if (LOCATION_LOCUS (new_locus) != UNKNOWN_LOCATION
     470       480360 :                           && LOCATION_LOCUS (locus) != UNKNOWN_LOCATION
     471      1373198 :                           && new_locus != locus)
     472              :                         new_target = NULL;
     473              :                       else
     474              :                         {
     475       999066 :                           if (LOCATION_LOCUS (new_locus) != UNKNOWN_LOCATION)
     476       472019 :                             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    559817420 :           else if ((mode & CLEANUP_THREADING) && may_thread)
     487              :             {
     488     27684713 :               edge t = thread_jump (e, target);
     489     27684713 :               if (t)
     490              :                 {
     491         6558 :                   if (!threaded_edges)
     492         6490 :                     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          210 :                       for (i = 0; i < nthreaded_edges; ++i)
     501          156 :                         if (threaded_edges[i] == t)
     502              :                           break;
     503           68 :                       if (i < nthreaded_edges)
     504              :                         {
     505           14 :                           counter = n_basic_blocks_for_fn (cfun);
     506           14 :                           break;
     507              :                         }
     508              :                     }
     509              : 
     510              :                   /* Detect an infinite loop across the start block.  */
     511         6544 :                   if (t->dest == b)
     512              :                     break;
     513              : 
     514         6006 :                   gcc_assert (nthreaded_edges
     515              :                               < (n_basic_blocks_for_fn (cfun)
     516              :                                  - NUM_FIXED_BLOCKS));
     517         6006 :                   threaded_edges[nthreaded_edges++] = t;
     518              : 
     519         6006 :                   new_target = t->dest;
     520         6006 :                   new_target_threaded = true;
     521              :                 }
     522              :             }
     523              : 
     524     30009155 :           if (!new_target)
     525              :             break;
     526              : 
     527     30009155 :           counter++;
     528              :           /* Do not turn non-crossing jump to crossing.  Depending on target
     529              :              it may require different instruction pattern.  */
     530     30009155 :           if ((e->flags & EDGE_CROSSING)
     531     29976986 :               || BB_PARTITION (first) == BB_PARTITION (new_target))
     532              :             {
     533     14775542 :               target = new_target;
     534     14775542 :               threaded |= new_target_threaded;
     535              :             }
     536              :         }
     537              : 
     538    560411517 :       if (counter >= n_basic_blocks_for_fn (cfun))
     539              :         {
     540       413297 :           if (dump_file)
     541            4 :             fprintf (dump_file, "Infinite loop in BB %i.\n",
     542              :                      target->index);
     543              :         }
     544    559998220 :       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     13702103 :           profile_count edge_count = e->count ();
     550     13702103 :           int n = 0;
     551              : 
     552     13702103 :           e->goto_locus = goto_locus;
     553              : 
     554              :           /* Don't force if target is exit block.  */
     555     13702103 :           if (threaded && target != EXIT_BLOCK_PTR_FOR_FN (cfun))
     556              :             {
     557         5940 :               notice_new_block (redirect_edge_and_branch_force (e, target));
     558         5940 :               if (dump_file)
     559            0 :                 fprintf (dump_file, "Conditionals threaded.\n");
     560              :             }
     561     13696163 :           else if (!redirect_edge_and_branch (e, target))
     562              :             {
     563      7319358 :               if (dump_file)
     564          191 :                 fprintf (dump_file,
     565              :                          "Forwarding edge %i->%i to %i failed.\n",
     566          191 :                          b->index, e->dest->index, target->index);
     567      7319358 :               ei_next (&ei);
     568      7319358 :               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      6493184 :           do
     575              :             {
     576      6493184 :               edge t;
     577              : 
     578      6493184 :               if (!single_succ_p (first))
     579              :                 {
     580         5992 :                   gcc_assert (n < nthreaded_edges);
     581         5992 :                   t = threaded_edges [n++];
     582         5992 :                   gcc_assert (t->src == first);
     583         5992 :                   update_bb_profile_for_threading (first, edge_count, t);
     584         5992 :                   update_br_prob_note (first);
     585              :                 }
     586              :               else
     587              :                 {
     588      6487192 :                   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      6487192 :                   if (n < nthreaded_edges
     594            0 :                       && first == threaded_edges [n]->src)
     595            0 :                     n++;
     596      6487192 :                   t = single_succ_edge (first);
     597              :                 }
     598              : 
     599      6493184 :               first = t->dest;
     600              :             }
     601      6493184 :           while (first != target);
     602              : 
     603      6382745 :           changed = true;
     604      6382745 :           continue;
     605      6382745 :         }
     606    546709414 :       ei_next (&ei);
     607              :     }
     608              : 
     609    393660377 :   free (threaded_edges);
     610    393660377 :   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        20483 : merge_blocks_move_predecessor_nojumps (basic_block a, basic_block b)
     620              : {
     621        20483 :   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        20483 :   if (BB_PARTITION (a) != BB_PARTITION (b))
     634              :     return;
     635              : 
     636        20483 :   barrier = next_nonnote_insn (BB_END (a));
     637        20483 :   gcc_assert (BARRIER_P (barrier));
     638        20483 :   delete_insn (barrier);
     639              : 
     640              :   /* Scramble the insn chain.  */
     641        20483 :   if (BB_END (a) != PREV_INSN (BB_HEAD (b)))
     642        20458 :     reorder_insns_nobb (BB_HEAD (a), BB_END (a), PREV_INSN (BB_HEAD (b)));
     643        20483 :   df_set_bb_dirty (a);
     644              : 
     645        20483 :   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        20483 :   unlink_block (a);
     652        20483 :   link_block (a, b->prev_bb);
     653              : 
     654              :   /* Now blocks A and B are contiguous.  Merge them.  */
     655        20483 :   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        30323 : merge_blocks_move_successor_nojumps (basic_block a, basic_block b)
     664              : {
     665        30323 :   rtx_insn *barrier, *real_b_end;
     666        30323 :   rtx_insn *label;
     667        30323 :   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        30323 :   if (BB_PARTITION (a) != BB_PARTITION (b))
     680            0 :     return;
     681              : 
     682        30323 :   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        30323 :   if (tablejump_p (BB_END (b), &label, &table)
     687        30323 :       && 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        30323 :   barrier = NEXT_INSN (BB_END (b));
     694        30323 :   if (barrier && BARRIER_P (barrier))
     695        30323 :     delete_insn (barrier);
     696              : 
     697              : 
     698              :   /* Scramble the insn chain.  */
     699        30323 :   reorder_insns_nobb (BB_HEAD (b), BB_END (b), BB_END (a));
     700              : 
     701              :   /* Restore the real end of b.  */
     702        30323 :   BB_END (b) = real_b_end;
     703              : 
     704        30323 :   if (dump_file)
     705           20 :     fprintf (dump_file, "Moved block %d after %d and merged.\n",
     706              :              b->index, a->index);
     707              : 
     708              :   /* Now blocks A and B are contiguous.  Merge them.  */
     709        30323 :   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      6786600 : merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
     726              : {
     727      6786600 :   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      6786600 :   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      6458260 :   if (e->flags & EDGE_FALLTHRU)
     744              :     {
     745      3771251 :       int b_index = b->index, c_index = c->index;
     746              : 
     747              :       /* Protect the loop latches.  */
     748      3771251 :       if (current_loops && c->loop_father->latch == c)
     749              :         return NULL;
     750              : 
     751      3726418 :       merge_blocks (b, c);
     752      3726418 :       update_forwarder_flag (b);
     753              : 
     754      3726418 :       if (dump_file)
     755          838 :         fprintf (dump_file, "Merged %d and %d without moving.\n",
     756              :                  b_index, c_index);
     757              : 
     758      4826226 :       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      2687009 :   else if (mode & CLEANUP_EXPENSIVE)
     764              :     {
     765       893337 :       edge tmp_edge, b_fallthru_edge;
     766       893337 :       bool c_has_outgoing_fallthru;
     767       893337 :       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       893337 :       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        52962 :       tmp_edge = find_fallthru_edge (c->succs);
     781        52962 :       c_has_outgoing_fallthru = (tmp_edge != NULL);
     782              : 
     783        52962 :       tmp_edge = find_fallthru_edge (b->preds);
     784        52962 :       b_has_incoming_fallthru = (tmp_edge != NULL);
     785        52962 :       b_fallthru_edge = tmp_edge;
     786        52962 :       next = b->prev_bb;
     787        52962 :       if (next == c)
     788           57 :         next = next->prev_bb;
     789              : 
     790              :       /* Otherwise, we're going to try to move C after B.  If C does
     791              :          not have an outgoing fallthru, then it can be moved
     792              :          immediately after B without introducing or modifying jumps.  */
     793        52962 :       if (! c_has_outgoing_fallthru)
     794              :         {
     795        30323 :           merge_blocks_move_successor_nojumps (b, c);
     796        30323 :           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        22639 :       if (b_has_incoming_fallthru)
     805              :         {
     806        21055 :           basic_block bb;
     807              : 
     808        21055 :           if (b_fallthru_edge->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
     809              :             return NULL;
     810        18899 :           bb = force_nonfallthru (b_fallthru_edge);
     811        18899 :           if (bb)
     812        14477 :             notice_new_block (bb);
     813              :         }
     814              : 
     815        20483 :       merge_blocks_move_predecessor_nojumps (b, c);
     816        20483 :       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    147162710 : merge_memattrs (rtx x, rtx y)
     828              : {
     829    147162710 :   int i;
     830    147162710 :   int j;
     831    147162710 :   enum rtx_code code;
     832    147162710 :   const char *fmt;
     833              : 
     834    147162710 :   if (x == y)
     835              :     return;
     836    109810100 :   if (x == 0 || y == 0)
     837              :     return;
     838              : 
     839    109773583 :   code = GET_CODE (x);
     840              : 
     841    109773583 :   if (code != GET_CODE (y))
     842              :     return;
     843              : 
     844    109773216 :   if (GET_MODE (x) != GET_MODE (y))
     845              :     return;
     846              : 
     847    109770177 :   if (code == MEM && !mem_attrs_eq_p (MEM_ATTRS (x), MEM_ATTRS (y)))
     848              :     {
     849        45319 :       if (! MEM_ATTRS (x))
     850          689 :         MEM_ATTRS (y) = 0;
     851        44630 :       else if (! MEM_ATTRS (y))
     852         1290 :         MEM_ATTRS (x) = 0;
     853              :       else
     854              :         {
     855        43340 :           if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y))
     856              :             {
     857         2865 :               set_mem_alias_set (x, 0);
     858         2865 :               set_mem_alias_set (y, 0);
     859              :             }
     860              : 
     861        43340 :           if (! mem_expr_equal_p (MEM_EXPR (x), MEM_EXPR (y)))
     862              :             {
     863        42570 :               set_mem_expr (x, 0);
     864        42570 :               set_mem_expr (y, 0);
     865        42570 :               clear_mem_offset (x);
     866        42570 :               clear_mem_offset (y);
     867              :             }
     868          770 :           else if (MEM_OFFSET_KNOWN_P (x) != MEM_OFFSET_KNOWN_P (y)
     869          770 :                    || (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        49901 :           if (!MEM_SIZE_KNOWN_P (x))
     877          206 :             clear_mem_size (y);
     878        49499 :           else if (!MEM_SIZE_KNOWN_P (y))
     879            0 :             clear_mem_size (x);
     880        43134 :           else if (known_le (MEM_SIZE (x), MEM_SIZE (y)))
     881        43090 :             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        56471 :           set_mem_align (x, MIN (MEM_ALIGN (x), MEM_ALIGN (y)));
     892        49918 :           set_mem_align (y, MEM_ALIGN (x));
     893              :         }
     894              :     }
     895    109770177 :   if (code == MEM)
     896              :     {
     897      6092872 :       if (MEM_READONLY_P (x) != MEM_READONLY_P (y))
     898              :         {
     899            6 :           MEM_READONLY_P (x) = 0;
     900            6 :           MEM_READONLY_P (y) = 0;
     901              :         }
     902      6092872 :       if (MEM_NOTRAP_P (x) != MEM_NOTRAP_P (y))
     903              :         {
     904          305 :           MEM_NOTRAP_P (x) = 0;
     905          305 :           MEM_NOTRAP_P (y) = 0;
     906              :         }
     907      6092872 :       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    109770177 :   fmt = GET_RTX_FORMAT (code);
     915    333555560 :   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     916              :     {
     917    223785383 :       switch (fmt[i])
     918              :         {
     919       379374 :         case 'E':
     920              :           /* Two vectors must have the same length.  */
     921       379374 :           if (XVECLEN (x, i) != XVECLEN (y, i))
     922              :             return;
     923              : 
     924      1121352 :           for (j = 0; j < XVECLEN (x, i); j++)
     925       741978 :             merge_memattrs (XVECEXP (x, i, j), XVECEXP (y, i, j));
     926              : 
     927              :           break;
     928              : 
     929    137748189 :         case 'e':
     930    137748189 :           merge_memattrs (XEXP (x, i), XEXP (y, i));
     931              :         }
     932              :     }
     933              :   return;
     934              : }
     935              : 
     936              : 
     937              :  /* Checks if patterns P1 and P2 are equivalent, apart from the possibly
     938              :     different single sets S1 and S2.  */
     939              : 
     940              : static bool
     941            2 : equal_different_set_p (rtx p1, rtx s1, rtx p2, rtx s2)
     942              : {
     943            2 :   int i;
     944            2 :   rtx e1, e2;
     945              : 
     946            2 :   if (p1 == s1 && p2 == s2)
     947              :     return true;
     948              : 
     949            0 :   if (GET_CODE (p1) != PARALLEL || GET_CODE (p2) != PARALLEL)
     950              :     return false;
     951              : 
     952            0 :   if (XVECLEN (p1, 0) != XVECLEN (p2, 0))
     953              :     return false;
     954              : 
     955            0 :   for (i = 0; i < XVECLEN (p1, 0); i++)
     956              :     {
     957            0 :       e1 = XVECEXP (p1, 0, i);
     958            0 :       e2 = XVECEXP (p2, 0, i);
     959            0 :       if (e1 == s1 && e2 == s2)
     960            0 :         continue;
     961            0 :       if (reload_completed
     962            0 :           ? rtx_renumbered_equal_p (e1, e2) : rtx_equal_p (e1, e2))
     963            0 :         continue;
     964              : 
     965              :       return false;
     966              :     }
     967              : 
     968              :   return true;
     969              : }
     970              : 
     971              : 
     972              : /* NOTE1 is the REG_EQUAL note, if any, attached to an insn
     973              :    that is a single_set with a SET_SRC of SRC1.  Similarly
     974              :    for NOTE2/SRC2.
     975              : 
     976              :    So effectively NOTE1/NOTE2 are an alternate form of
     977              :    SRC1/SRC2 respectively.
     978              : 
     979              :    Return nonzero if SRC1 or NOTE1 has the same constant
     980              :    integer value as SRC2 or NOTE2.   Else return zero.  */
     981              : static int
     982      7603046 : values_equal_p (rtx note1, rtx note2, rtx src1, rtx src2)
     983              : {
     984      7603046 :   if (note1
     985      7603046 :       && note2
     986      1280471 :       && CONST_INT_P (XEXP (note1, 0))
     987      7657403 :       && rtx_equal_p (XEXP (note1, 0), XEXP (note2, 0)))
     988              :     return 1;
     989              : 
     990      7603046 :   if (!note1
     991      7603046 :       && !note2
     992      5862357 :       && CONST_INT_P (src1)
     993      2446577 :       && CONST_INT_P (src2)
     994      9950950 :       && rtx_equal_p (src1, src2))
     995              :     return 1;
     996              : 
     997      7603046 :   if (note1
     998      1545162 :       && CONST_INT_P (src2)
     999      7734107 :       && rtx_equal_p (XEXP (note1, 0), src2))
    1000              :     return 1;
    1001              : 
    1002      7603046 :   if (note2
    1003      1475998 :       && CONST_INT_P (src1)
    1004      7670470 :       && rtx_equal_p (XEXP (note2, 0), src1))
    1005              :     return 1;
    1006              : 
    1007              :   return 0;
    1008              : }
    1009              : 
    1010              : /* Examine register notes on I1 and I2 and return:
    1011              :    - dir_forward if I1 can be replaced by I2, or
    1012              :    - dir_backward if I2 can be replaced by I1, or
    1013              :    - dir_both if both are the case.  */
    1014              : 
    1015              : static enum replace_direction
    1016     13566021 : can_replace_by (rtx_insn *i1, rtx_insn *i2)
    1017              : {
    1018     13566021 :   rtx s1, s2, d1, d2, src1, src2, note1, note2;
    1019     13566021 :   bool c1, c2;
    1020              : 
    1021              :   /* Check for 2 sets.  */
    1022     13566021 :   s1 = single_set (i1);
    1023     13566021 :   s2 = single_set (i2);
    1024     13566021 :   if (s1 == NULL_RTX || s2 == NULL_RTX)
    1025              :     return dir_none;
    1026              : 
    1027              :   /* Check that the 2 sets set the same dest.  */
    1028     12797069 :   d1 = SET_DEST (s1);
    1029     12797069 :   d2 = SET_DEST (s2);
    1030     25594138 :   if (!(reload_completed
    1031     12797069 :         ? 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      7603046 :   note1 = find_reg_equal_equiv_note (i1);
    1037      7603046 :   note2 = find_reg_equal_equiv_note (i2);
    1038              : 
    1039      7603046 :   src1 = SET_SRC (s1);
    1040      7603046 :   src2 = SET_SRC (s2);
    1041              : 
    1042      7603046 :   if (!values_equal_p (note1, note2, src1, src2))
    1043              :     return dir_none;
    1044              : 
    1045            2 :   if (!equal_different_set_p (PATTERN (i1), s1, PATTERN (i2), s2))
    1046              :     return dir_none;
    1047              : 
    1048              :   /* Although the 2 sets set dest to the same value, we cannot replace
    1049              :        (set (dest) (const_int))
    1050              :      by
    1051              :        (set (dest) (reg))
    1052              :      because we don't know if the reg is live and has the same value at the
    1053              :      location of replacement.  */
    1054            2 :   c1 = CONST_INT_P (src1);
    1055            2 :   c2 = CONST_INT_P (src2);
    1056            2 :   if (c1 && c2)
    1057              :     return dir_both;
    1058            2 :   else if (c2)
    1059              :     return dir_forward;
    1060            2 :   else if (c1)
    1061              :     return dir_backward;
    1062              : 
    1063              :   return dir_none;
    1064              : }
    1065              : 
    1066              : /* Merges directions A and B.  */
    1067              : 
    1068              : static enum replace_direction
    1069     23392540 : 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     16032782 :   if (a == dir_both)
    1083              :     return b;
    1084      3750801 :   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       611660 : insns_have_identical_cfa_notes (rtx_insn *i1, rtx_insn *i2)
    1107              : {
    1108       611660 :   rtx n1, n2;
    1109       611660 :   for (n1 = REG_NOTES (i1), n2 = REG_NOTES (i2); ;
    1110       481982 :        n1 = XEXP (n1, 1), n2 = XEXP (n2, 1))
    1111              :     {
    1112              :       /* Skip over reg notes not related to CFI information.  */
    1113      1601200 :       while (n1 && !reg_note_cfa_p[REG_NOTE_KIND (n1)])
    1114        25576 :         n1 = XEXP (n1, 1);
    1115      1117893 :       while (n2 && !reg_note_cfa_p[REG_NOTE_KIND (n2)])
    1116        24251 :         n2 = XEXP (n2, 1);
    1117      1093642 :       if (n1 == NULL_RTX && n2 == NULL_RTX)
    1118              :         return true;
    1119       594750 :       if (n1 == NULL_RTX || n2 == NULL_RTX)
    1120              :         return false;
    1121       590041 :       if (XEXP (n1, 0) == XEXP (n2, 0))
    1122              :         ;
    1123       590035 :       else if (XEXP (n1, 0) == NULL_RTX || XEXP (n2, 0) == NULL_RTX)
    1124              :         return false;
    1125      1180070 :       else if (!(reload_completed
    1126       590035 :                  ? 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     39601070 : old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx_insn *i1, rtx_insn *i2)
    1139              : {
    1140     39601070 :   rtx p1, p2;
    1141              : 
    1142              :   /* Verify that I1 and I2 are equivalent.  */
    1143     39601070 :   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     34070989 :   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     33993343 :   p1 = find_reg_note (i1, REG_ARGS_SIZE, NULL);
    1153     33993343 :   p2 = find_reg_note (i2, REG_ARGS_SIZE, NULL);
    1154     33993343 :   if (p1 && p2)
    1155              :     {
    1156      3881648 :       p1 = XEXP (p1, 0);
    1157      3881648 :       p2 = XEXP (p2, 0);
    1158      3881648 :       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      3780688 :       if (!frame_pointer_needed
    1164      3780688 :           && known_eq (find_args_size_adjust (i1), HOST_WIDE_INT_MIN))
    1165           22 :         return dir_none;
    1166              :     }
    1167     30111695 :   else if (p1 || p2)
    1168              :     return dir_none;
    1169              : 
    1170              :   /* Do not allow cross-jumping between frame related insns and other
    1171              :      insns.  */
    1172     32348817 :   if (RTX_FRAME_RELATED_P (i1) != RTX_FRAME_RELATED_P (i2))
    1173              :     return dir_none;
    1174              : 
    1175     31745010 :   p1 = PATTERN (i1);
    1176     31745010 :   p2 = PATTERN (i2);
    1177              : 
    1178     31745010 :   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     29406694 :   if (CALL_P (i1))
    1194              :     {
    1195              :       /* Ensure the same EH region.  */
    1196     11601847 :       rtx n1 = find_reg_note (i1, REG_EH_REGION, 0);
    1197     11601847 :       rtx n2 = find_reg_note (i2, REG_EH_REGION, 0);
    1198              : 
    1199     11601847 :       if (!n1 && n2)
    1200              :         return dir_none;
    1201              : 
    1202     11516261 :       if (n1 && (!n2 || XEXP (n1, 0) != XEXP (n2, 0)))
    1203              :         return dir_none;
    1204              : 
    1205     10732835 :       if (!rtx_equal_p (CALL_INSN_FUNCTION_USAGE (i1),
    1206     10732835 :                         CALL_INSN_FUNCTION_USAGE (i2))
    1207      7185549 :           || CALL_INSN_ABI_ID (i1) != CALL_INSN_ABI_ID (i2)
    1208     17918384 :           || 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      7185549 :       if (flag_sanitize & SANITIZE_ADDRESS)
    1214              :         {
    1215       332074 :           rtx call = get_call_rtx_from (i1);
    1216       332074 :           if (call && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
    1217              :             {
    1218       332074 :               rtx symbol = XEXP (XEXP (call, 0), 0);
    1219       332074 :               if (SYMBOL_REF_DECL (symbol)
    1220       332074 :                   && TREE_CODE (SYMBOL_REF_DECL (symbol)) == FUNCTION_DECL)
    1221              :                 {
    1222       332074 :                   if ((DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (symbol))
    1223       332074 :                        == BUILT_IN_NORMAL)
    1224       330160 :                       && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol))
    1225              :                          >= BUILT_IN_ASAN_REPORT_LOAD1
    1226       660734 :                       && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol))
    1227              :                          <= BUILT_IN_ASAN_STOREN)
    1228              :                     return dir_none;
    1229              :                 }
    1230              :             }
    1231              :         }
    1232              : 
    1233      6857839 :       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     24604752 :   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     24491984 :   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     24491984 :   if (reload_completed
    1273     24491984 :       ? rtx_renumbered_equal_p (p1, p2) : rtx_equal_p (p1, p2))
    1274              :     return dir_both;
    1275              : 
    1276     13566021 :   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      8672543 : merge_notes (rtx_insn *i1, rtx_insn *i2)
    1284              : {
    1285              :   /* If the merged insns have different REG_EQUAL notes, then
    1286              :      remove them.  */
    1287      8672543 :   rtx equiv1 = find_reg_equal_equiv_note (i1);
    1288      8672543 :   rtx equiv2 = find_reg_equal_equiv_note (i2);
    1289              : 
    1290      8672543 :   if (equiv1 && !equiv2)
    1291        21741 :     remove_note (i1, equiv1);
    1292      8650802 :   else if (!equiv1 && equiv2)
    1293         6606 :     remove_note (i2, equiv2);
    1294      8644196 :   else if (equiv1 && equiv2
    1295      8644196 :            && !rtx_equal_p (XEXP (equiv1, 0), XEXP (equiv2, 0)))
    1296              :     {
    1297          531 :       remove_note (i1, equiv1);
    1298          531 :       remove_note (i2, equiv2);
    1299              :     }
    1300      8672543 : }
    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     48321606 : walk_to_nondebug_insn (rtx_insn **i1, basic_block *bb1, bool follow_fallthru,
    1310              :                        bool *did_fallthru)
    1311              : {
    1312     48321606 :   edge fallthru;
    1313              : 
    1314     48321606 :   *did_fallthru = false;
    1315              : 
    1316              :   /* Ignore notes.  */
    1317     65665606 :   while (!NONDEBUG_INSN_P (*i1))
    1318              :     {
    1319     18472320 :       if (*i1 != BB_HEAD (*bb1))
    1320              :         {
    1321     17122408 :           *i1 = PREV_INSN (*i1);
    1322     17122408 :           continue;
    1323              :         }
    1324              : 
    1325      1349912 :       if (!follow_fallthru)
    1326              :         return;
    1327              : 
    1328      1179392 :       fallthru = find_fallthru_edge ((*bb1)->preds);
    1329       511383 :       if (!fallthru || fallthru->src == ENTRY_BLOCK_PTR_FOR_FN (cfun)
    1330      1690712 :           || !single_succ_p (fallthru->src))
    1331              :         return;
    1332              : 
    1333       221592 :       *bb1 = fallthru->src;
    1334       221592 :       *i1 = BB_END (*bb1);
    1335       221592 :       *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     15692140 : flow_find_cross_jump (basic_block bb1, basic_block bb2, rtx_insn **f1,
    1353              :                       rtx_insn **f2, enum replace_direction *dir_p)
    1354              : {
    1355     15692140 :   rtx_insn *i1, *i2, *last1, *last2, *afterlast1, *afterlast2;
    1356     15692140 :   int ninsns = 0;
    1357     15692140 :   enum replace_direction dir, last_dir, afterlast_dir;
    1358     15692140 :   bool follow_fallthru, did_fallthru;
    1359              : 
    1360     15692140 :   if (dir_p)
    1361     15692140 :     dir = *dir_p;
    1362              :   else
    1363              :     dir = dir_both;
    1364     15692140 :   afterlast_dir = dir;
    1365     15692140 :   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     15692140 :   i1 = BB_END (bb1);
    1371     15692140 :   last1 = afterlast1 = last2 = afterlast2 = NULL;
    1372     15692140 :   if (onlyjump_p (i1)
    1373     15692140 :       || (returnjump_p (i1) && !side_effects_p (PATTERN (i1))))
    1374              :     {
    1375     14089870 :       last1 = i1;
    1376     14089870 :       i1 = PREV_INSN (i1);
    1377              :     }
    1378              : 
    1379     15692140 :   i2 = BB_END (bb2);
    1380     15692140 :   if (onlyjump_p (i2)
    1381     15692140 :       || (returnjump_p (i2) && !side_effects_p (PATTERN (i2))))
    1382              :     {
    1383     11484464 :       last2 = i2;
    1384              :       /* Count everything except for unconditional jump as insn.
    1385              :          Don't count any jumps if dir_p is NULL.  */
    1386     11484464 :       if (!simplejump_p (i2) && !returnjump_p (i2) && last1 && dir_p)
    1387              :         ninsns++;
    1388     11484464 :       i2 = PREV_INSN (i2);
    1389              :     }
    1390              : 
    1391     32629466 :   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     24160803 :       follow_fallthru = dir_p && dir != dir_forward;
    1410     24160803 :       walk_to_nondebug_insn (&i1, &bb1, follow_fallthru, &did_fallthru);
    1411     24160803 :       if (did_fallthru)
    1412        27210 :         dir = dir_backward;
    1413              : 
    1414     24160803 :       follow_fallthru = dir_p && dir != dir_backward;
    1415     24160803 :       walk_to_nondebug_insn (&i2, &bb2, follow_fallthru, &did_fallthru);
    1416     24160803 :       if (did_fallthru)
    1417       194372 :         dir = dir_forward;
    1418              : 
    1419     24160803 :       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     23392540 :       if (BB_PARTITION (BLOCK_FOR_INSN (i1))
    1425     23392540 :           != BB_PARTITION (BLOCK_FOR_INSN (i2))
    1426     23392540 :           && reload_completed)
    1427              :         break;
    1428              : 
    1429     23392540 :       dir = merge_dir (dir, old_insns_match_p (0, i1, i2));
    1430     20750644 :       if (dir == dir_none || (!dir_p && dir != dir_both))
    1431              :         break;
    1432              : 
    1433      8468663 :       merge_memattrs (i1, i2);
    1434              : 
    1435              :       /* Don't begin a cross-jump with a NOTE insn.  */
    1436      8468663 :       if (INSN_P (i1))
    1437              :         {
    1438      8468663 :           merge_notes (i1, i2);
    1439              : 
    1440      8468663 :           afterlast1 = last1, afterlast2 = last2;
    1441      8468663 :           last1 = i1, last2 = i2;
    1442      8468663 :           afterlast_dir = last_dir;
    1443      8468663 :           last_dir = dir;
    1444      8468663 :           if (active_insn_p (i1))
    1445      8362183 :             ninsns++;
    1446              :         }
    1447              : 
    1448      8468663 :       i1 = PREV_INSN (i1);
    1449      8468663 :       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     15692140 :   if (ninsns)
    1456              :     {
    1457      5122121 :       bb1 = BLOCK_FOR_INSN (last1);
    1458     12906448 :       while (last1 != BB_HEAD (bb1) && !NONDEBUG_INSN_P (PREV_INSN (last1)))
    1459              :         last1 = PREV_INSN (last1);
    1460              : 
    1461      9978230 :       if (last1 != BB_HEAD (bb1) && LABEL_P (PREV_INSN (last1)))
    1462              :         last1 = PREV_INSN (last1);
    1463              : 
    1464      5122121 :       bb2 = BLOCK_FOR_INSN (last2);
    1465     13034586 :       while (last2 != BB_HEAD (bb2) && !NONDEBUG_INSN_P (PREV_INSN (last2)))
    1466              :         last2 = PREV_INSN (last2);
    1467              : 
    1468      9633059 :       if (last2 != BB_HEAD (bb2) && LABEL_P (PREV_INSN (last2)))
    1469              :         last2 = PREV_INSN (last2);
    1470              : 
    1471      5122121 :       *f1 = last1;
    1472      5122121 :       *f2 = last2;
    1473              :     }
    1474              : 
    1475     15692140 :   if (dir_p)
    1476     15692140 :     *dir_p = last_dir;
    1477     15692140 :   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      4481122 : flow_find_head_matching_sequence (basic_block bb1, basic_block bb2, rtx_insn **f1,
    1488              :                                   rtx_insn **f2, int stop_after)
    1489              : {
    1490      4481122 :   rtx_insn *i1, *i2, *last1, *last2, *beforelast1, *beforelast2;
    1491      4481122 :   int ninsns = 0;
    1492      4481122 :   edge e;
    1493      4481122 :   edge_iterator ei;
    1494      4481122 :   int nehedges1 = 0, nehedges2 = 0;
    1495              : 
    1496     10758384 :   FOR_EACH_EDGE (e, ei, bb1->succs)
    1497      6277262 :     if (e->flags & EDGE_EH)
    1498       329240 :       nehedges1++;
    1499     11084511 :   FOR_EACH_EDGE (e, ei, bb2->succs)
    1500      6603389 :     if (e->flags & EDGE_EH)
    1501       365705 :       nehedges2++;
    1502              : 
    1503      4481122 :   i1 = BB_HEAD (bb1);
    1504      4481122 :   i2 = BB_HEAD (bb2);
    1505      4481122 :   last1 = beforelast1 = last2 = beforelast2 = NULL;
    1506              : 
    1507       191072 :   while (true)
    1508              :     {
    1509              :       /* Ignore notes, except NOTE_INSN_EPILOGUE_BEG.  */
    1510     21109760 :       while (!NONDEBUG_INSN_P (i1) && i1 != BB_END (bb1))
    1511              :         {
    1512     16264658 :           if (NOTE_P (i1) && NOTE_KIND (i1) == NOTE_INSN_EPILOGUE_BEG)
    1513              :             break;
    1514     16246494 :           i1 = NEXT_INSN (i1);
    1515              :         }
    1516              : 
    1517     20715056 :       while (!NONDEBUG_INSN_P (i2) && i2 != BB_END (bb2))
    1518              :         {
    1519     16082025 :           if (NOTE_P (i2) && NOTE_KIND (i2) == NOTE_INSN_EPILOGUE_BEG)
    1520              :             break;
    1521     16042862 :           i2 = NEXT_INSN (i2);
    1522              :         }
    1523              : 
    1524      4672194 :       if ((i1 == BB_END (bb1) && !NONDEBUG_INSN_P (i1))
    1525      4660417 :           || (i2 == BB_END (bb2) && !NONDEBUG_INSN_P (i2)))
    1526              :         break;
    1527              : 
    1528      4655687 :       if (NOTE_P (i1) || NOTE_P (i2)
    1529      4600399 :           || 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      3770558 :       if ((i1 == BB_END (bb1) && i2 != BB_END (bb2)
    1537       216288 :            && nehedges1 > 0)
    1538      3731711 :           || (i2 == BB_END (bb2) && i1 != BB_END (bb1)
    1539       234390 :               && nehedges2 > 0)
    1540      3704096 :           || (i1 == BB_END (bb1) && i2 == BB_END (bb2)
    1541        26642 :               && nehedges1 != nehedges2))
    1542              :         break;
    1543              : 
    1544      3700710 :       if (old_insns_match_p (0, i1, i2) != dir_both)
    1545              :         break;
    1546              : 
    1547       203880 :       merge_memattrs (i1, i2);
    1548              : 
    1549              :       /* Don't begin a cross-jump with a NOTE insn.  */
    1550       203880 :       if (INSN_P (i1))
    1551              :         {
    1552       203880 :           merge_notes (i1, i2);
    1553              : 
    1554       203880 :           beforelast1 = last1, beforelast2 = last2;
    1555       203880 :           last1 = i1, last2 = i2;
    1556       203880 :           if (!stop_after || active_insn_p (i1))
    1557       203880 :             ninsns++;
    1558              :         }
    1559              : 
    1560       203880 :       if (i1 == BB_END (bb1) || i2 == BB_END (bb2)
    1561       191072 :           || (stop_after > 0 && ninsns == stop_after))
    1562              :         break;
    1563              : 
    1564       191072 :       i1 = NEXT_INSN (i1);
    1565       191072 :       i2 = NEXT_INSN (i2);
    1566              :     }
    1567              : 
    1568      4481122 :   if (ninsns)
    1569              :     {
    1570       113915 :       *f1 = last1;
    1571       113915 :       *f2 = last2;
    1572              :     }
    1573              : 
    1574      4481122 :   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     46284514 : outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
    1585              : {
    1586     46284514 :   int nehedges1 = 0, nehedges2 = 0;
    1587     46284514 :   edge fallthru1 = 0, fallthru2 = 0;
    1588     46284514 :   edge e1, e2;
    1589     46284514 :   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     46284514 :   if (crtl->shrink_wrapped
    1596      1209067 :       && single_succ_p (bb1)
    1597       466324 :       && single_succ (bb1) == EXIT_BLOCK_PTR_FOR_FN (cfun)
    1598       152367 :       && (!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        64508 :           || (single_succ_edge (bb1)->flags & EDGE_FAKE) != 0)
    1602     46372453 :       && !(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     46231360 :   if (single_succ_p (bb1)
    1608     18755333 :       && (single_succ_edge (bb1)->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0
    1609     61537069 :       && (!JUMP_P (BB_END (bb1)) || simplejump_p (BB_END (bb1))))
    1610     15045751 :     return (single_succ_p (bb2)
    1611     13704520 :             && (single_succ_edge (bb2)->flags
    1612     13704520 :                 & (EDGE_COMPLEX | EDGE_FAKE)) == 0
    1613     28694135 :             && (!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     31185609 :   if (EDGE_COUNT (bb1->succs) == 2
    1618     27396704 :       && any_condjump_p (BB_END (bb1))
    1619     49861431 :       && onlyjump_p (BB_END (bb1)))
    1620              :     {
    1621     18675822 :       edge b1, f1, b2, f2;
    1622     18675822 :       bool reverse, match;
    1623     18675822 :       rtx set1, set2, cond1, cond2;
    1624     18675822 :       enum rtx_code code1, code2;
    1625              : 
    1626     18675822 :       if (EDGE_COUNT (bb2->succs) != 2
    1627      8489874 :           || !any_condjump_p (BB_END (bb2))
    1628     27133404 :           || !onlyjump_p (BB_END (bb2)))
    1629     10218240 :         return false;
    1630              : 
    1631      8457582 :       b1 = BRANCH_EDGE (bb1);
    1632      8457582 :       b2 = BRANCH_EDGE (bb2);
    1633      8457582 :       f1 = FALLTHRU_EDGE (bb1);
    1634      8457582 :       f2 = FALLTHRU_EDGE (bb2);
    1635              : 
    1636              :       /* Get around possible forwarders on fallthru edges.  Other cases
    1637              :          should be optimized out already.  */
    1638      8457582 :       if (FORWARDER_BLOCK_P (f1->dest))
    1639      3281910 :         f1 = single_succ_edge (f1->dest);
    1640              : 
    1641      8457582 :       if (FORWARDER_BLOCK_P (f2->dest))
    1642      2492819 :         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      8457582 :       if (FORWARDER_BLOCK_P (f1->dest)
    1648      8452834 :           || FORWARDER_BLOCK_P (f2->dest)
    1649      8447174 :           || FORWARDER_BLOCK_P (b1->dest)
    1650      8422597 :           || FORWARDER_BLOCK_P (b2->dest))
    1651              :         return false;
    1652              : 
    1653      8396997 :       if (f1->dest == f2->dest && b1->dest == b2->dest)
    1654              :         reverse = false;
    1655      8199801 :       else if (f1->dest == b2->dest && b1->dest == f2->dest)
    1656              :         reverse = true;
    1657              :       else
    1658              :         return false;
    1659              : 
    1660       325783 :       set1 = pc_set (BB_END (bb1));
    1661       325783 :       set2 = pc_set (BB_END (bb2));
    1662       325783 :       if ((XEXP (SET_SRC (set1), 1) == pc_rtx)
    1663       325783 :           != (XEXP (SET_SRC (set2), 1) == pc_rtx))
    1664            0 :         reverse = !reverse;
    1665              : 
    1666       325783 :       cond1 = XEXP (SET_SRC (set1), 0);
    1667       325783 :       cond2 = XEXP (SET_SRC (set2), 0);
    1668       325783 :       code1 = GET_CODE (cond1);
    1669       325783 :       if (reverse)
    1670       128587 :         code2 = reversed_comparison_code (cond2, BB_END (bb2));
    1671              :       else
    1672       197196 :         code2 = GET_CODE (cond2);
    1673              : 
    1674       325783 :       if (code2 == UNKNOWN)
    1675              :         return false;
    1676              : 
    1677              :       /* Verify codes and operands match.  */
    1678       926350 :       match = ((code1 == code2
    1679       281648 :                 && rtx_renumbered_equal_p (XEXP (cond1, 0), XEXP (cond2, 0))
    1680       279544 :                 && rtx_renumbered_equal_p (XEXP (cond1, 1), XEXP (cond2, 1)))
    1681       327887 :                || (code1 == swap_condition (code2)
    1682         3565 :                    && rtx_renumbered_equal_p (XEXP (cond1, 1),
    1683         3565 :                                               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       279544 :       if (match
    1692       279544 :           && optimize_bb_for_speed_p (bb1)
    1693       253330 :           && optimize_bb_for_speed_p (bb2))
    1694              :         {
    1695       244418 :           profile_probability prob2;
    1696              : 
    1697       244418 :           if (b1->dest == b2->dest)
    1698       150244 :             prob2 = b2->probability;
    1699              :           else
    1700              :             /* Do not use f2 probability as f2 may be forwarded.  */
    1701        94174 :             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       244418 :           if (b1->probability.differs_lot_from_p (prob2))
    1707              :             {
    1708         4760 :               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         4760 :               return false;
    1718              :             }
    1719              :         }
    1720              : 
    1721       321023 :       if (dump_file && match)
    1722           16 :         fprintf (dump_file, "Conditionals in bb %i and %i match.\n",
    1723              :                  bb1->index, bb2->index);
    1724              : 
    1725       321023 :       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     12509787 :     {
    1734     12509787 :       rtx_insn *label1, *label2;
    1735     12509787 :       rtx_jump_table_data *table1, *table2;
    1736              : 
    1737     12509787 :       if (tablejump_p (BB_END (bb1), &label1, &table1)
    1738        76767 :           && tablejump_p (BB_END (bb2), &label2, &table2)
    1739     12512112 :           && 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         2325 :           if (label1 != label2 && !rtx_referenced_p (label2, BB_END (bb1)))
    1749              :             {
    1750              :               /* Set IDENTICAL to true when the tables are identical.  */
    1751         2325 :               bool identical = false;
    1752         2325 :               rtx p1, p2;
    1753              : 
    1754         2325 :               p1 = PATTERN (table1);
    1755         2325 :               p2 = PATTERN (table2);
    1756         2325 :               if (GET_CODE (p1) == ADDR_VEC && rtx_equal_p (p1, p2))
    1757              :                 {
    1758              :                   identical = true;
    1759              :                 }
    1760         2014 :               else if (GET_CODE (p1) == ADDR_DIFF_VEC
    1761          394 :                        && (XVECLEN (p1, 1) == XVECLEN (p2, 1))
    1762          288 :                        && rtx_equal_p (XEXP (p1, 2), XEXP (p2, 2))
    1763         2302 :                        && rtx_equal_p (XEXP (p1, 3), XEXP (p2, 3)))
    1764              :                 {
    1765          288 :                   int i;
    1766              : 
    1767          288 :                   identical = true;
    1768         1172 :                   for (i = XVECLEN (p1, 1) - 1; i >= 0 && identical; i--)
    1769          884 :                     if (!rtx_equal_p (XVECEXP (p1, 1, i), XVECEXP (p2, 1, i)))
    1770              :                       identical = false;
    1771              :                 }
    1772              : 
    1773          288 :               if (identical)
    1774              :                 {
    1775          358 :                   bool match;
    1776              : 
    1777              :                   /* Temporarily replace references to LABEL1 with LABEL2
    1778              :                      in BB1->END so that we could compare the instructions.  */
    1779          358 :                   replace_label_in_insn (BB_END (bb1), label1, label2, false);
    1780              : 
    1781          358 :                   match = (old_insns_match_p (mode, BB_END (bb1), BB_END (bb2))
    1782              :                            == dir_both);
    1783          358 :                   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          358 :                   replace_label_in_insn (BB_END (bb1), label2, label1, false);
    1792              : 
    1793         2325 :                   return match;
    1794              :                 }
    1795              :             }
    1796         1967 :           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     12507462 :   rtx_insn *last1 = BB_END (bb1);
    1805     12507462 :   rtx_insn *last2 = BB_END (bb2);
    1806     12507553 :   while (!NOTE_INSN_BASIC_BLOCK_P (last1) &&
    1807     12390111 :          (DEBUG_INSN_P (last1) || NOTE_P (last1)))
    1808           91 :     last1 = PREV_INSN (last1);
    1809     12536288 :   while (!NOTE_INSN_BASIC_BLOCK_P (last2) &&
    1810     12422532 :          (DEBUG_INSN_P (last2) || NOTE_P (last2)))
    1811        28826 :     last2 = PREV_INSN (last2);
    1812     12507462 :   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     12507462 :   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      6992187 :   if (EDGE_COUNT (bb1->succs) != EDGE_COUNT (bb2->succs))
    1823              :     return false;
    1824              : 
    1825      2330716 :   bool nonfakeedges = false;
    1826      5711273 :   FOR_EACH_EDGE (e1, ei, bb1->succs)
    1827              :     {
    1828      3380557 :       e2 = EDGE_SUCC (bb2, ei.index);
    1829              : 
    1830      3380557 :       if ((e1->flags & EDGE_FAKE) == 0)
    1831      2430649 :         nonfakeedges = true;
    1832              : 
    1833      3380557 :       if (e1->flags & EDGE_EH)
    1834      1086659 :         nehedges1++;
    1835              : 
    1836      3380557 :       if (e2->flags & EDGE_EH)
    1837      1086659 :         nehedges2++;
    1838              : 
    1839      3380557 :       if (e1->flags & EDGE_FALLTHRU)
    1840      1133951 :         fallthru1 = e1;
    1841      3380557 :       if (e2->flags & EDGE_FALLTHRU)
    1842      1133951 :         fallthru2 = e2;
    1843              :     }
    1844              : 
    1845              :   /* If number of edges of various types does not match, fail.  */
    1846      2330716 :   if (nehedges1 != nehedges2
    1847      2330716 :       || (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      2330716 :   if (!nonfakeedges
    1857       949908 :       && !ACCUMULATE_OUTGOING_ARGS
    1858      3280617 :       && (!INSN_P (last1)
    1859       949901 :           || !find_reg_note (last1, REG_ARGS_SIZE, NULL)))
    1860           11 :     return false;
    1861              : 
    1862              :   /* fallthru edges must be forwarded to the same destination.  */
    1863      2330705 :   if (fallthru1)
    1864              :     {
    1865      1133951 :       basic_block d1 = (FORWARDER_BLOCK_P (fallthru1->dest)
    1866      1133951 :                         ? single_succ (fallthru1->dest) : fallthru1->dest);
    1867      1133951 :       basic_block d2 = (FORWARDER_BLOCK_P (fallthru2->dest)
    1868      1133951 :                         ? single_succ (fallthru2->dest) : fallthru2->dest);
    1869              : 
    1870      1133951 :       if (d1 != d2)
    1871              :         return false;
    1872              :     }
    1873              : 
    1874              :   /* Ensure the same EH region.  */
    1875      1768666 :   {
    1876      1768666 :     rtx n1 = find_reg_note (last1, REG_EH_REGION, 0);
    1877      1768666 :     rtx n2 = find_reg_note (last2, REG_EH_REGION, 0);
    1878              : 
    1879      1768666 :     if (!n1 && n2)
    1880              :       return false;
    1881              : 
    1882      1768666 :     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      4024492 :   FOR_EACH_EDGE (e1, ei, bb2->succs)
    1889              :     {
    1890      2255856 :       edge e2;
    1891      2255856 :       edge_iterator ei;
    1892      2255856 :       basic_block d1 = e1->dest;
    1893              : 
    1894      2255856 :       if (FORWARDER_BLOCK_P (d1))
    1895       589830 :         d1 = EDGE_SUCC (d1, 0)->dest;
    1896              : 
    1897      2744516 :       FOR_EACH_EDGE (e2, ei, bb1->succs)
    1898              :         {
    1899      2744516 :           basic_block d2 = e2->dest;
    1900      2744516 :           if (FORWARDER_BLOCK_P (d2))
    1901       760430 :             d2 = EDGE_SUCC (d2, 0)->dest;
    1902      2744516 :           if (d1 == d2)
    1903              :             break;
    1904              :         }
    1905              : 
    1906      2255856 :       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       350366 : block_has_preserve_label (basic_block bb)
    1917              : {
    1918       350366 :   return (bb
    1919       350366 :           && block_label (bb)
    1920       650149 :           && 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     50946608 : try_crossjump_to_edge (int mode, edge e1, edge e2,
    1931              :                        enum replace_direction dir)
    1932              : {
    1933     50946608 :   int nmatch;
    1934     50946608 :   basic_block src1 = e1->src, src2 = e2->src;
    1935     50946608 :   basic_block redirect_to, redirect_from, to_remove;
    1936     50946608 :   basic_block osrc1, osrc2, redirect_edges_to, tmp;
    1937     50946608 :   rtx_insn *newpos1, *newpos2;
    1938     50946608 :   edge s;
    1939     50946608 :   edge_iterator ei;
    1940              : 
    1941     50946608 :   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     50946608 :   if (single_pred_p (src1)
    1948     50946608 :       && FORWARDER_BLOCK_P (src1))
    1949     11726671 :     e1 = single_pred_edge (src1), src1 = e1->src;
    1950              : 
    1951     50946608 :   if (single_pred_p (src2)
    1952     50946397 :       && FORWARDER_BLOCK_P (src2))
    1953      5498019 :     e2 = single_pred_edge (src2), src2 = e2->src;
    1954              : 
    1955              :   /* Nothing to do if we reach ENTRY, or a common source block.  */
    1956     50946608 :   if (src1 == ENTRY_BLOCK_PTR_FOR_FN (cfun) || src2
    1957              :       == ENTRY_BLOCK_PTR_FOR_FN (cfun))
    1958              :     return false;
    1959     50946168 :   if (src1 == src2)
    1960              :     return false;
    1961              : 
    1962              :   /* Seeing more than 1 forwarder blocks would confuse us later...  */
    1963     50946046 :   if (FORWARDER_BLOCK_P (e1->dest)
    1964     50946046 :       && FORWARDER_BLOCK_P (single_succ (e1->dest)))
    1965              :     return false;
    1966              : 
    1967     50934549 :   if (FORWARDER_BLOCK_P (e2->dest)
    1968     50934549 :       && 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     50934021 :   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     46458249 :   if (BB_PARTITION (src1) != BB_PARTITION (src2)
    1978       173735 :       && reload_completed)
    1979              :     return false;
    1980              : 
    1981              :   /* Look for the common insn sequence, part the first ...  */
    1982     46284514 :   if (!outgoing_edges_match (mode, src1, src2))
    1983              :     return false;
    1984              : 
    1985              :   /* ... and part the second.  */
    1986     15692140 :   nmatch = flow_find_cross_jump (src1, src2, &newpos1, &newpos2, &dir);
    1987              : 
    1988     15692140 :   osrc1 = src1;
    1989     15692140 :   osrc2 = src2;
    1990     15692140 :   if (newpos1 != NULL_RTX)
    1991      5122121 :     src1 = BLOCK_FOR_INSN (newpos1);
    1992     15692140 :   if (newpos2 != NULL_RTX)
    1993      5122121 :     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     66319758 :   if (EDGE_COUNT (src1->preds) == 0 || EDGE_COUNT (src2->preds) == 0)
    1998              :     return false;
    1999              : 
    2000     15692140 :   if (dir == dir_backward)
    2001              :     {
    2002         1791 :       std::swap (osrc1, osrc2);
    2003         1791 :       std::swap (src1, src2);
    2004         1791 :       std::swap (e1, e2);
    2005         1791 :       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     15692140 :   if ((nmatch < param_min_crossjump_insns)
    2013     15574771 :       && (newpos1 != BB_HEAD (src1)))
    2014              :     return false;
    2015              : 
    2016              :   /* Avoid deleting preserve label when redirecting ABNORMAL edges.  */
    2017       350366 :   if (block_has_preserve_label (e1->dest)
    2018       350366 :       && (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       318990 :   {
    2027       318990 :       rtx_insn *label1, *label2;
    2028       318990 :       rtx_jump_table_data *table1, *table2;
    2029              : 
    2030       318990 :       if (tablejump_p (BB_END (osrc1), &label1, &table1)
    2031            4 :           && tablejump_p (BB_END (osrc2), &label2, &table2)
    2032       318994 :           && label1 != label2)
    2033              :         {
    2034            4 :           rtx_insn *insn;
    2035              : 
    2036              :           /* Replace references to LABEL1 with LABEL2.  */
    2037         9246 :           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         9242 :               if (insn != BB_END (osrc1))
    2043         9238 :                 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       318990 :   if (newpos2 == BB_HEAD (src2)
    2052       318990 :       && !(EDGE_PRED (src2, 0)->flags & EDGE_EH))
    2053              :     redirect_to = src2;
    2054              :   else
    2055              :     {
    2056        76613 :       if (newpos2 == BB_HEAD (src2))
    2057              :         {
    2058              :           /* Skip possible basic block header.  */
    2059         5586 :           if (LABEL_P (newpos2))
    2060         5586 :             newpos2 = NEXT_INSN (newpos2);
    2061         5586 :           while (DEBUG_INSN_P (newpos2))
    2062            0 :             newpos2 = NEXT_INSN (newpos2);
    2063         5586 :           if (NOTE_P (newpos2))
    2064         5586 :             newpos2 = NEXT_INSN (newpos2);
    2065         5781 :           while (DEBUG_INSN_P (newpos2))
    2066          195 :             newpos2 = NEXT_INSN (newpos2);
    2067              :         }
    2068              : 
    2069        76613 :       if (dump_file)
    2070            0 :         fprintf (dump_file, "Splitting bb %i before %i insns\n",
    2071              :                  src2->index, nmatch);
    2072        76613 :       redirect_to = split_block (src2, PREV_INSN (newpos2))->dest;
    2073              :     }
    2074              : 
    2075       318990 :   if (dump_file)
    2076            4 :     fprintf (dump_file,
    2077              :              "Cross jumping from bb %i to bb %i; %i common insns\n",
    2078              :              src1->index, src2->index, nmatch);
    2079              : 
    2080              :   /* We may have some registers visible through the block.  */
    2081       318990 :   df_set_bb_dirty (redirect_to);
    2082              : 
    2083       318990 :   if (osrc2 == src2)
    2084              :     redirect_edges_to = redirect_to;
    2085              :   else
    2086        10450 :     redirect_edges_to = osrc2;
    2087              : 
    2088              :   /* Recompute the counts of destinations of outgoing edges.  */
    2089       703766 :   FOR_EACH_EDGE (s, ei, redirect_edges_to->succs)
    2090              :     {
    2091       384776 :       edge s2;
    2092       384776 :       edge_iterator ei;
    2093       384776 :       basic_block d = s->dest;
    2094              : 
    2095       384776 :       if (FORWARDER_BLOCK_P (d))
    2096        28353 :         d = single_succ (d);
    2097              : 
    2098       450796 :       FOR_EACH_EDGE (s2, ei, src1->succs)
    2099              :         {
    2100       450796 :           basic_block d2 = s2->dest;
    2101       450796 :           if (FORWARDER_BLOCK_P (d2))
    2102        97636 :             d2 = single_succ (d2);
    2103       450796 :           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       384776 :       if (FORWARDER_BLOCK_P (s->dest))
    2111        28353 :         s->dest->count += s->count ();
    2112              : 
    2113       384776 :       if (FORWARDER_BLOCK_P (s2->dest))
    2114        74746 :         s2->dest->count -= s->count ();
    2115              : 
    2116       384776 :       s->probability = s->probability.combine_with_count
    2117       384776 :                           (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       341074 :   do
    2127              :     {
    2128       330032 :       tmp->count += src1->count;
    2129       330032 :       if (tmp == redirect_edges_to)
    2130              :         break;
    2131        11042 :       tmp = find_fallthru_edge (tmp->succs)->dest;
    2132              :     }
    2133              :   while (true);
    2134       318990 :   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       318990 :   if (LABEL_P (newpos1))
    2140       124845 :     newpos1 = NEXT_INSN (newpos1);
    2141              : 
    2142       334243 :   while (DEBUG_INSN_P (newpos1))
    2143        15253 :     newpos1 = NEXT_INSN (newpos1);
    2144              : 
    2145       318990 :   if (NOTE_INSN_BASIC_BLOCK_P (newpos1))
    2146       237716 :     newpos1 = NEXT_INSN (newpos1);
    2147              : 
    2148              :   /* Skip also prologue and function markers.  */
    2149       797759 :   while (DEBUG_INSN_P (newpos1)
    2150       797759 :          || (NOTE_P (newpos1)
    2151        13334 :              && (NOTE_KIND (newpos1) == NOTE_INSN_PROLOGUE_END
    2152        13334 :                  || NOTE_KIND (newpos1) == NOTE_INSN_FUNCTION_BEG)))
    2153       478769 :     newpos1 = NEXT_INSN (newpos1);
    2154              : 
    2155       318990 :   redirect_from = split_block (src1, PREV_INSN (newpos1))->src;
    2156       318990 :   to_remove = single_succ (redirect_from);
    2157              : 
    2158       318990 :   redirect_edge_and_branch_force (single_succ_edge (redirect_from), redirect_to);
    2159       318990 :   delete_basic_block (to_remove);
    2160              : 
    2161       318990 :   update_forwarder_flag (redirect_from);
    2162       318990 :   if (redirect_to != src2)
    2163        76613 :     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     29783286 : try_crossjump_bb (int mode, basic_block bb)
    2174              : {
    2175     29783286 :   edge e, e2, fallthru;
    2176     29783286 :   bool changed;
    2177     29783286 :   unsigned max, ix, ix2;
    2178              : 
    2179              :   /* Nothing to do if there is not at least two incoming edges.  */
    2180     29987521 :   if (EDGE_COUNT (bb->preds) < 2)
    2181              :     return false;
    2182              : 
    2183              :   /* Don't crossjump if this block ends in a computed jump,
    2184              :      unless we are optimizing for size.  */
    2185      8184925 :   if (optimize_bb_for_size_p (bb)
    2186      1293530 :       && bb != EXIT_BLOCK_PTR_FOR_FN (cfun)
    2187      9439212 :       && computed_jump_p (BB_END (bb)))
    2188              :     return false;
    2189              : 
    2190              :   /* If we are partitioning hot/cold basic blocks, we don't want to
    2191              :      mess up unconditional or indirect jumps that cross between hot
    2192              :      and cold sections.
    2193              : 
    2194              :      Basic block partitioning may result in some jumps that appear to
    2195              :      be optimizable (or blocks that appear to be mergeable), but which really
    2196              :      must be left untouched (they are required to make it safely across
    2197              :      partition boundaries).  See the comments at the top of
    2198              :      bb-reorder.cc:partition_hot_cold_basic_blocks for complete details.  */
    2199              : 
    2200      8184895 :   if (BB_PARTITION (EDGE_PRED (bb, 0)->src) !=
    2201      8184895 :                                         BB_PARTITION (EDGE_PRED (bb, 1)->src)
    2202      8184895 :       || (EDGE_PRED (bb, 0)->flags & EDGE_CROSSING))
    2203              :     return false;
    2204              : 
    2205              :   /* It is always cheapest to redirect a block that ends in a branch to
    2206              :      a block that falls through into BB, as that adds no branches to the
    2207              :      program.  We'll try that combination first.  */
    2208      7983551 :   fallthru = NULL;
    2209      7983551 :   max = param_max_crossjump_edges;
    2210              : 
    2211      7983551 :   if (EDGE_COUNT (bb->preds) > max)
    2212              :     return false;
    2213              : 
    2214      7980690 :   fallthru = find_fallthru_edge (bb->preds);
    2215              : 
    2216      7980690 :   changed = false;
    2217     39164923 :   for (ix = 0; ix < EDGE_COUNT (bb->preds);)
    2218              :     {
    2219     23203543 :       e = EDGE_PRED (bb, ix);
    2220     23203543 :       ix++;
    2221              : 
    2222              :       /* As noted above, first try with the fallthru predecessor (or, a
    2223              :          fallthru predecessor if we are in cfglayout mode).  */
    2224     23203543 :       if (fallthru)
    2225              :         {
    2226              :           /* Don't combine the fallthru edge into anything else.
    2227              :              If there is a match, we'll do it the other way around.  */
    2228     17123792 :           if (e == fallthru)
    2229      6454670 :             continue;
    2230              :           /* If nothing changed since the last attempt, there is nothing
    2231              :              we can do.  */
    2232     10669122 :           if (!first_pass
    2233      4231491 :               && !((e->src->flags & BB_MODIFIED)
    2234      3373641 :                    || (fallthru->src->flags & BB_MODIFIED)))
    2235      3005341 :             continue;
    2236              : 
    2237      7663781 :           if (try_crossjump_to_edge (mode, e, fallthru, dir_forward))
    2238              :             {
    2239       139848 :               changed = true;
    2240       139848 :               ix = 0;
    2241       139848 :               continue;
    2242              :             }
    2243              :         }
    2244              : 
    2245              :       /* Non-obvious work limiting check: Recognize that we're going
    2246              :          to call try_crossjump_bb on every basic block.  So if we have
    2247              :          two blocks with lots of outgoing edges (a switch) and they
    2248              :          share lots of common destinations, then we would do the
    2249              :          cross-jump check once for each common destination.
    2250              : 
    2251              :          Now, if the blocks actually are cross-jump candidates, then
    2252              :          all of their destinations will be shared.  Which means that
    2253              :          we only need check them for cross-jump candidacy once.  We
    2254              :          can eliminate redundant checks of crossjump(A,B) by arbitrarily
    2255              :          choosing to do the check from the block for which the edge
    2256              :          in question is the first successor of A.  */
    2257     13603684 :       if (EDGE_SUCC (e->src, 0) != e)
    2258      2736404 :         continue;
    2259              : 
    2260    166005617 :       for (ix2 = 0; ix2 < EDGE_COUNT (bb->preds); ix2++)
    2261              :         {
    2262    124133246 :           e2 = EDGE_PRED (bb, ix2);
    2263              : 
    2264    124133246 :           if (e2 == e)
    2265     10782733 :             continue;
    2266              : 
    2267              :           /* We've already checked the fallthru edge above.  */
    2268    113350513 :           if (e2 == fallthru)
    2269      6029379 :             continue;
    2270              : 
    2271              :           /* The "first successor" check above only prevents multiple
    2272              :              checks of crossjump(A,B).  In order to prevent redundant
    2273              :              checks of crossjump(B,A), require that A be the block
    2274              :              with the lowest index.  */
    2275    107321134 :           if (e->src->index > e2->src->index)
    2276     53737886 :             continue;
    2277              : 
    2278              :           /* If nothing changed since the last attempt, there is nothing
    2279              :              we can do.  */
    2280     53583248 :           if (!first_pass
    2281     13554529 :               && !((e->src->flags & BB_MODIFIED)
    2282     11152368 :                    || (e2->src->flags & BB_MODIFIED)))
    2283     10300421 :             continue;
    2284              : 
    2285              :           /* Both e and e2 are not fallthru edges, so we can crossjump in either
    2286              :              direction.  */
    2287     43282827 :           if (try_crossjump_to_edge (mode, e, e2, dir_both))
    2288              :             {
    2289              :               changed = true;
    2290              :               ix = 0;
    2291              :               break;
    2292              :             }
    2293              :         }
    2294              :     }
    2295              : 
    2296      7980690 :   if (changed)
    2297       151938 :     crossjumps_occurred = true;
    2298              : 
    2299              :   return changed;
    2300              : }
    2301              : 
    2302              : /* Search the successors of BB for common insn sequences.  When found,
    2303              :    share code between them by moving it across the basic block
    2304              :    boundary.  Return true if any changes made.  */
    2305              : 
    2306              : static bool
    2307     28594069 : try_head_merge_bb (basic_block bb)
    2308              : {
    2309     28594069 :   basic_block final_dest_bb = NULL;
    2310     28594069 :   int max_match = INT_MAX;
    2311     28594069 :   edge e0;
    2312     28594069 :   rtx_insn **headptr, **currptr, **nextptr;
    2313     28594069 :   bool changed, moveall;
    2314     28594069 :   unsigned ix;
    2315     28594069 :   rtx_insn *e0_last_head;
    2316     28594069 :   rtx cond;
    2317     28594069 :   rtx_insn *move_before;
    2318     28594069 :   unsigned nedges = EDGE_COUNT (bb->succs);
    2319     28594069 :   rtx_insn *jump = BB_END (bb);
    2320     28594069 :   regset live, live_union;
    2321              : 
    2322              :   /* Nothing to do if there is not at least two outgoing edges.  */
    2323     28594069 :   if (nedges < 2)
    2324              :     return false;
    2325              : 
    2326              :   /* Don't crossjump if this block ends in a computed jump,
    2327              :      unless we are optimizing for size.  */
    2328     14703886 :   if (optimize_bb_for_size_p (bb)
    2329      1701738 :       && bb != EXIT_BLOCK_PTR_FOR_FN (cfun)
    2330     16405624 :       && computed_jump_p (BB_END (bb)))
    2331              :     return false;
    2332              : 
    2333     14703858 :   cond = get_condition (jump, &move_before, true, false);
    2334     14703858 :   if (cond == NULL_RTX)
    2335      1942335 :     move_before = jump;
    2336              : 
    2337     44364151 :   for (ix = 0; ix < nedges; ix++)
    2338     29660293 :     if (EDGE_SUCC (bb, ix)->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
    2339              :       return false;
    2340              : 
    2341     27302106 :   for (ix = 0; ix < nedges; ix++)
    2342              :     {
    2343     22824626 :       edge e = EDGE_SUCC (bb, ix);
    2344     22824626 :       basic_block other_bb = e->dest;
    2345              : 
    2346     22824626 :       if (df_get_bb_dirty (other_bb))
    2347              :         {
    2348       537917 :           block_was_dirty = true;
    2349       537917 :           return false;
    2350              :         }
    2351              : 
    2352     22286709 :       if (e->flags & EDGE_ABNORMAL)
    2353              :         return false;
    2354              : 
    2355              :       /* Normally, all destination blocks must only be reachable from this
    2356              :          block, i.e. they must have one incoming edge.
    2357              : 
    2358              :          There is one special case we can handle, that of multiple consecutive
    2359              :          jumps where the first jumps to one of the targets of the second jump.
    2360              :          This happens frequently in switch statements for default labels.
    2361              :          The structure is as follows:
    2362              :          FINAL_DEST_BB
    2363              :          ....
    2364              :          if (cond) jump A;
    2365              :          fall through
    2366              :          BB
    2367              :          jump with targets A, B, C, D...
    2368              :          A
    2369              :          has two incoming edges, from FINAL_DEST_BB and BB
    2370              : 
    2371              :          In this case, we can try to move the insns through BB and into
    2372              :          FINAL_DEST_BB.  */
    2373     20419309 :       if (EDGE_COUNT (other_bb->preds) != 1)
    2374              :         {
    2375      8154693 :           edge incoming_edge, incoming_bb_other_edge;
    2376      8154693 :           edge_iterator ei;
    2377              : 
    2378      8154693 :           if (final_dest_bb != NULL
    2379      8154693 :               || EDGE_COUNT (other_bb->preds) != 2)
    2380      7821061 :             return false;
    2381              : 
    2382              :           /* We must be able to move the insns across the whole block.  */
    2383      4446417 :           move_before = BB_HEAD (bb);
    2384     29183389 :           while (!NONDEBUG_INSN_P (move_before))
    2385     24736972 :             move_before = NEXT_INSN (move_before);
    2386              : 
    2387      4446417 :           if (EDGE_COUNT (bb->preds) != 1)
    2388              :             return false;
    2389      2644325 :           incoming_edge = EDGE_PRED (bb, 0);
    2390      2644325 :           final_dest_bb = incoming_edge->src;
    2391      9985429 :           if (EDGE_COUNT (final_dest_bb->succs) != 2)
    2392              :             return false;
    2393      3124070 :           FOR_EACH_EDGE (incoming_bb_other_edge, ei, final_dest_bb->succs)
    2394      3124070 :             if (incoming_bb_other_edge != incoming_edge)
    2395              :               break;
    2396      2164368 :           if (incoming_bb_other_edge->dest != other_bb)
    2397              :             return false;
    2398              :         }
    2399              :     }
    2400              : 
    2401      4477480 :   e0 = EDGE_SUCC (bb, 0);
    2402      4477480 :   e0_last_head = NULL;
    2403      4477480 :   changed = false;
    2404              : 
    2405      4591395 :   for (ix = 1; ix < nedges; ix++)
    2406              :     {
    2407      4481122 :       edge e = EDGE_SUCC (bb, ix);
    2408      4481122 :       rtx_insn *e0_last, *e_last;
    2409      4481122 :       int nmatch;
    2410              : 
    2411      4481122 :       nmatch = flow_find_head_matching_sequence (e0->dest, e->dest,
    2412              :                                                  &e0_last, &e_last, 0);
    2413      4481122 :       if (nmatch == 0)
    2414      4367207 :         return false;
    2415              : 
    2416       113915 :       if (nmatch < max_match)
    2417              :         {
    2418       110499 :           max_match = nmatch;
    2419       110499 :           e0_last_head = e0_last;
    2420              :         }
    2421              :     }
    2422              : 
    2423              :   /* If we matched an entire block, we probably have to avoid moving the
    2424              :      last insn.  */
    2425       110273 :   if (max_match > 0
    2426       110273 :       && e0_last_head == BB_END (e0->dest)
    2427       118997 :       && (find_reg_note (e0_last_head, REG_EH_REGION, 0)
    2428         7082 :           || control_flow_insn_p (e0_last_head)))
    2429              :     {
    2430         1654 :       max_match--;
    2431         1654 :       if (max_match == 0)
    2432              :         return false;
    2433          260 :       e0_last_head = prev_real_nondebug_insn (e0_last_head);
    2434              :     }
    2435              : 
    2436       108879 :   if (max_match == 0)
    2437              :     return false;
    2438              : 
    2439              :   /* We must find a union of the live registers at each of the end points.  */
    2440       108879 :   live = BITMAP_ALLOC (NULL);
    2441       108879 :   live_union = BITMAP_ALLOC (NULL);
    2442              : 
    2443       108879 :   currptr = XNEWVEC (rtx_insn *, nedges);
    2444       108879 :   headptr = XNEWVEC (rtx_insn *, nedges);
    2445       108879 :   nextptr = XNEWVEC (rtx_insn *, nedges);
    2446              : 
    2447       329929 :   for (ix = 0; ix < nedges; ix++)
    2448              :     {
    2449       221050 :       int j;
    2450       221050 :       basic_block merge_bb = EDGE_SUCC (bb, ix)->dest;
    2451       221050 :       rtx_insn *head = BB_HEAD (merge_bb);
    2452              : 
    2453      1427669 :       while (!NONDEBUG_INSN_P (head))
    2454      1206619 :         head = NEXT_INSN (head);
    2455       221050 :       headptr[ix] = head;
    2456       221050 :       currptr[ix] = head;
    2457              : 
    2458              :       /* Compute the end point and live information  */
    2459       359331 :       for (j = 1; j < max_match; j++)
    2460       195549 :         do
    2461       195549 :           head = NEXT_INSN (head);
    2462       195549 :         while (!NONDEBUG_INSN_P (head));
    2463       221050 :       simulate_backwards_to_point (merge_bb, live, head);
    2464       221050 :       IOR_REG_SET (live_union, live);
    2465              :     }
    2466              : 
    2467              :   /* If we're moving across two blocks, verify the validity of the
    2468              :      first move, then adjust the target and let the loop below deal
    2469              :      with the final move.  */
    2470       108879 :   if (final_dest_bb != NULL)
    2471              :     {
    2472         6176 :       rtx_insn *move_upto;
    2473              : 
    2474         6176 :       moveall = can_move_insns_across (currptr[0], e0_last_head, move_before,
    2475              :                                        jump, e0->dest, live_union,
    2476              :                                        NULL, &move_upto);
    2477         6176 :       if (!moveall)
    2478              :         {
    2479         5029 :           if (move_upto == NULL_RTX)
    2480         4649 :             goto out;
    2481              : 
    2482         1165 :           while (e0_last_head != move_upto)
    2483              :             {
    2484          785 :               df_simulate_one_insn_backwards (e0->dest, e0_last_head,
    2485              :                                               live_union);
    2486          785 :               e0_last_head = PREV_INSN (e0_last_head);
    2487              :             }
    2488              :         }
    2489         1527 :       if (e0_last_head == NULL_RTX)
    2490            0 :         goto out;
    2491              : 
    2492         1527 :       jump = BB_END (final_dest_bb);
    2493         1527 :       cond = get_condition (jump, &move_before, true, false);
    2494         1527 :       if (cond == NULL_RTX)
    2495            0 :         move_before = jump;
    2496              :     }
    2497              : 
    2498       179247 :   do
    2499              :     {
    2500       179247 :       rtx_insn *move_upto;
    2501       179247 :       moveall = can_move_insns_across (currptr[0], e0_last_head,
    2502              :                                        move_before, jump, e0->dest, live_union,
    2503              :                                        NULL, &move_upto);
    2504       179247 :       if (!moveall && move_upto == NULL_RTX)
    2505              :         {
    2506       141033 :           if (jump == move_before)
    2507              :             break;
    2508              : 
    2509              :           /* Try again, using a different insertion point.  */
    2510        71250 :           move_before = jump;
    2511              : 
    2512        71250 :           continue;
    2513              :         }
    2514              : 
    2515        38214 :       if (final_dest_bb && !moveall)
    2516              :         /* We haven't checked whether a partial move would be OK for the first
    2517              :            move, so we have to fail this case.  */
    2518              :         break;
    2519              : 
    2520        56778 :       changed = true;
    2521        56778 :       for (;;)
    2522              :         {
    2523        56778 :           if (currptr[0] == move_upto)
    2524              :             break;
    2525        56028 :           for (ix = 0; ix < nedges; ix++)
    2526              :             {
    2527        37374 :               rtx_insn *curr = currptr[ix];
    2528        57043 :               do
    2529        57043 :                 curr = NEXT_INSN (curr);
    2530        57043 :               while (!NONDEBUG_INSN_P (curr));
    2531        37374 :               currptr[ix] = curr;
    2532              :             }
    2533              :         }
    2534              : 
    2535              :       /* If we can't currently move all of the identical insns, remember
    2536              :          each insn after the range that we'll merge.  */
    2537        38124 :       if (!moveall)
    2538        15222 :         for (ix = 0; ix < nedges; ix++)
    2539              :           {
    2540        10162 :             rtx_insn *curr = currptr[ix];
    2541        13836 :             do
    2542        13836 :               curr = NEXT_INSN (curr);
    2543        13836 :             while (!NONDEBUG_INSN_P (curr));
    2544        10162 :             nextptr[ix] = curr;
    2545              :           }
    2546              : 
    2547        38124 :       reorder_insns (headptr[0], currptr[0], PREV_INSN (move_before));
    2548        38124 :       df_set_bb_dirty (EDGE_SUCC (bb, 0)->dest);
    2549        38124 :       if (final_dest_bb != NULL)
    2550         1432 :         df_set_bb_dirty (final_dest_bb);
    2551        38124 :       df_set_bb_dirty (bb);
    2552       115565 :       for (ix = 1; ix < nedges; ix++)
    2553              :         {
    2554        39317 :           df_set_bb_dirty (EDGE_SUCC (bb, ix)->dest);
    2555        39317 :           delete_insn_chain (headptr[ix], currptr[ix], false);
    2556              :         }
    2557        38124 :       if (!moveall)
    2558              :         {
    2559         5060 :           if (jump == move_before)
    2560              :             break;
    2561              : 
    2562              :           /* For the unmerged insns, try a different insertion point.  */
    2563         3767 :           move_before = jump;
    2564              : 
    2565        11301 :           for (ix = 0; ix < nedges; ix++)
    2566         7534 :             currptr[ix] = headptr[ix] = nextptr[ix];
    2567              :         }
    2568              :     }
    2569       108081 :   while (!moveall);
    2570              : 
    2571        33064 :  out:
    2572       108879 :   free (currptr);
    2573       108879 :   free (headptr);
    2574       108879 :   free (nextptr);
    2575              : 
    2576       108879 :   crossjumps_occurred |= changed;
    2577              : 
    2578       108879 :   return changed;
    2579              : }
    2580              : 
    2581              : /* Return true if BB contains just bb note, or bb note followed
    2582              :    by only DEBUG_INSNs.  */
    2583              : 
    2584              : static bool
    2585     16173334 : trivially_empty_bb_p (basic_block bb)
    2586              : {
    2587     16173334 :   rtx_insn *insn = BB_END (bb);
    2588              : 
    2589         5662 :   while (1)
    2590              :     {
    2591     16178996 :       if (insn == BB_HEAD (bb))
    2592              :         return true;
    2593     16178103 :       if (!DEBUG_INSN_P (insn))
    2594              :         return false;
    2595         5662 :       insn = PREV_INSN (insn);
    2596              :     }
    2597              : }
    2598              : 
    2599              : /* Return true if BB contains just a return and possibly a USE of the
    2600              :    return value.  Fill in *RET and *USE with the return and use insns
    2601              :    if any found, otherwise NULL.  All CLOBBERs are ignored.  */
    2602              : 
    2603              : bool
    2604    398119446 : bb_is_just_return (basic_block bb, rtx_insn **ret, rtx_insn **use)
    2605              : {
    2606    398119446 :   *ret = *use = NULL;
    2607    398119446 :   rtx_insn *insn;
    2608              : 
    2609    398119446 :   if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
    2610              :     return false;
    2611              : 
    2612    525869907 :   FOR_BB_INSNS_REVERSE (bb, insn)
    2613    512730147 :     if (NONDEBUG_INSN_P (insn))
    2614              :       {
    2615    393836437 :         rtx pat = PATTERN (insn);
    2616              : 
    2617    393836437 :         if (!*ret && ANY_RETURN_P (pat))
    2618      7399948 :           *ret = insn;
    2619      7753486 :         else if (*ret && !*use && GET_CODE (pat) == USE
    2620      1128593 :             && REG_P (XEXP (pat, 0))
    2621    387565082 :             && REG_FUNCTION_VALUE_P (XEXP (pat, 0)))
    2622      1125447 :           *use = insn;
    2623    385311042 :         else if (GET_CODE (pat) != CLOBBER)
    2624              :           return false;
    2625              :       }
    2626              : 
    2627     13139760 :   return !!*ret;
    2628              : }
    2629              : 
    2630              : /* Do simple CFG optimizations - basic block merging, simplifying of jump
    2631              :    instructions etc.  Return nonzero if changes were made.  */
    2632              : 
    2633              : static bool
    2634     21813665 : try_optimize_cfg (int mode)
    2635              : {
    2636     21813665 :   bool changed_overall = false;
    2637     21813665 :   bool changed;
    2638     21813665 :   int iterations = 0;
    2639     21813665 :   basic_block bb, b, next;
    2640              : 
    2641     21813665 :   if (mode & (CLEANUP_CROSSJUMP | CLEANUP_THREADING))
    2642      2971942 :     clear_bb_flags ();
    2643              : 
    2644     21813665 :   crossjumps_occurred = false;
    2645              : 
    2646    314095816 :   FOR_EACH_BB_FN (bb, cfun)
    2647    292282151 :     update_forwarder_flag (bb);
    2648              : 
    2649     21813665 :   if (! targetm.cannot_modify_jumps_p ())
    2650              :     {
    2651     21813665 :       first_pass = true;
    2652              :       /* Attempt to merge blocks as made possible by edge removal.  If
    2653              :          a block has only one successor, and the successor has only
    2654              :          one predecessor, they may be combined.  */
    2655     51299304 :       do
    2656              :         {
    2657     25649652 :           block_was_dirty = false;
    2658     25649652 :           changed = false;
    2659     25649652 :           iterations++;
    2660              : 
    2661     25649652 :           if (dump_file)
    2662         1775 :             fprintf (dump_file,
    2663              :                      "\n\ntry_optimize_cfg iteration %i\n\n",
    2664              :                      iterations);
    2665              : 
    2666     25649652 :           for (b = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb; b
    2667    424812037 :                != EXIT_BLOCK_PTR_FOR_FN (cfun);)
    2668              :             {
    2669    399162385 :               basic_block c;
    2670    399162385 :               edge s;
    2671    399162385 :               bool changed_here = false;
    2672              : 
    2673              :               /* Delete trivially dead basic blocks.  This is either
    2674              :                  blocks with no predecessors, or empty blocks with no
    2675              :                  successors.  However if the empty block with no
    2676              :                  successors is the successor of the ENTRY_BLOCK, it is
    2677              :                  kept.  This ensures that the ENTRY_BLOCK will have a
    2678              :                  successor which is a precondition for many RTL
    2679              :                  passes.  Empty blocks may result from expanding
    2680              :                  __builtin_unreachable ().  */
    2681    399162385 :               if (EDGE_COUNT (b->preds) == 0
    2682    399162385 :                   || (EDGE_COUNT (b->succs) == 0
    2683     16173334 :                       && trivially_empty_bb_p (b)
    2684          893 :                       && single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))->dest
    2685              :                       != b))
    2686              :                 {
    2687      5366091 :                   c = b->prev_bb;
    2688      5366091 :                   if (EDGE_COUNT (b->preds) > 0)
    2689              :                     {
    2690          893 :                       edge e;
    2691          893 :                       edge_iterator ei;
    2692              : 
    2693          893 :                       if (current_ir_type () == IR_RTL_CFGLAYOUT)
    2694              :                         {
    2695           51 :                           rtx_insn *insn;
    2696           51 :                           for (insn = BB_FOOTER (b);
    2697           51 :                                insn; insn = NEXT_INSN (insn))
    2698           51 :                             if (BARRIER_P (insn))
    2699              :                               break;
    2700           51 :                           if (insn)
    2701          102 :                             FOR_EACH_EDGE (e, ei, b->preds)
    2702           51 :                               if ((e->flags & EDGE_FALLTHRU))
    2703              :                                 {
    2704           51 :                                   if (BB_FOOTER (b)
    2705           51 :                                       && BB_FOOTER (e->src) == NULL)
    2706              :                                     {
    2707           51 :                                       BB_FOOTER (e->src) = BB_FOOTER (b);
    2708           51 :                                       BB_FOOTER (b) = NULL;
    2709              :                                     }
    2710              :                                   else
    2711            0 :                                     emit_barrier_after_bb (e->src);
    2712              :                                 }
    2713              :                         }
    2714              :                       else
    2715              :                         {
    2716          842 :                           rtx_insn *last = get_last_bb_insn (b);
    2717          842 :                           if (last && BARRIER_P (last))
    2718         1684 :                             FOR_EACH_EDGE (e, ei, b->preds)
    2719          842 :                               if ((e->flags & EDGE_FALLTHRU))
    2720          842 :                                 emit_barrier_after (BB_END (e->src));
    2721              :                         }
    2722              :                     }
    2723      5366091 :                   delete_basic_block (b);
    2724      5366091 :                   changed = true;
    2725              :                   /* Avoid trying to remove the exit block.  */
    2726      5366091 :                   b = (c == ENTRY_BLOCK_PTR_FOR_FN (cfun) ? c->next_bb : c);
    2727      5502008 :                   continue;
    2728      5366091 :                 }
    2729              : 
    2730              :               /* Remove code labels no longer used.  */
    2731    393796294 :               if (single_pred_p (b)
    2732    286069014 :                   && (single_pred_edge (b)->flags & EDGE_FALLTHRU)
    2733    202021611 :                   && !(single_pred_edge (b)->flags & EDGE_COMPLEX)
    2734    199174612 :                   && LABEL_P (BB_HEAD (b))
    2735       813337 :                   && !LABEL_PRESERVE_P (BB_HEAD (b))
    2736              :                   /* If the previous block ends with a branch to this
    2737              :                      block, we can't delete the label.  Normally this
    2738              :                      is a condjump that is yet to be simplified, but
    2739              :                      if CASE_DROPS_THRU, this can be a tablejump with
    2740              :                      some element going to the same place as the
    2741              :                      default (fallthru).  */
    2742    394594569 :                   && (single_pred (b) == ENTRY_BLOCK_PTR_FOR_FN (cfun)
    2743       798221 :                       || !JUMP_P (BB_END (single_pred (b)))
    2744       607534 :                       || ! label_is_jump_target_p (BB_HEAD (b),
    2745       607534 :                                                    BB_END (single_pred (b)))))
    2746              :                 {
    2747       792002 :                   delete_insn (BB_HEAD (b));
    2748       792002 :                   if (dump_file)
    2749           37 :                     fprintf (dump_file, "Deleted label in block %i.\n",
    2750              :                              b->index);
    2751              :                 }
    2752              : 
    2753              :               /* If we fall through an empty block, we can remove it.  */
    2754    393932211 :               if (!(mode & (CLEANUP_CFGLAYOUT | CLEANUP_NO_INSN_DEL))
    2755     83773195 :                   && single_pred_p (b)
    2756     61947148 :                   && (single_pred_edge (b)->flags & EDGE_FALLTHRU)
    2757     43939021 :                   && !LABEL_P (BB_HEAD (b))
    2758     43586868 :                   && FORWARDER_BLOCK_P (b)
    2759              :                   /* Note that forwarder_block_p true ensures that
    2760              :                      there is a successor for this block.  */
    2761      5222137 :                   && (single_succ_edge (b)->flags & EDGE_FALLTHRU)
    2762    394018121 :                   && n_basic_blocks_for_fn (cfun) > NUM_FIXED_BLOCKS + 1)
    2763              :                 {
    2764       135917 :                   if (dump_file)
    2765           11 :                     fprintf (dump_file,
    2766              :                              "Deleting fallthru block %i.\n",
    2767              :                              b->index);
    2768              : 
    2769         2659 :                   c = ((b->prev_bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
    2770       135917 :                        ? b->next_bb : b->prev_bb);
    2771       135917 :                   redirect_edge_succ_nodup (single_pred_edge (b),
    2772              :                                             single_succ (b));
    2773       135917 :                   delete_basic_block (b);
    2774       135917 :                   changed = true;
    2775       135917 :                   b = c;
    2776       135917 :                   continue;
    2777              :                 }
    2778              : 
    2779              :               /* Merge B with its single successor, if any.  */
    2780    393660377 :               if (single_succ_p (b)
    2781    172164694 :                   && (s = single_succ_edge (b))
    2782    172164694 :                   && !(s->flags & EDGE_COMPLEX)
    2783    163708774 :                   && (c = s->dest) != EXIT_BLOCK_PTR_FOR_FN (cfun)
    2784    402477037 :                   && single_pred_p (c)
    2785    400828929 :                   && b != c)
    2786              :                 {
    2787              :                   /* When not in cfg_layout mode use code aware of reordering
    2788              :                      INSN.  This code possibly creates new basic blocks so it
    2789              :                      does not fit merge_blocks interface and is kept here in
    2790              :                      hope that it will become useless once more of compiler
    2791              :                      is transformed to use cfg_layout mode.  */
    2792              : 
    2793      8816660 :                   if ((mode & CLEANUP_CFGLAYOUT)
    2794      8816660 :                       && can_merge_blocks_p (b, c))
    2795              :                     {
    2796       813931 :                       merge_blocks (b, c);
    2797       813931 :                       update_forwarder_flag (b);
    2798       813931 :                       changed_here = true;
    2799              :                     }
    2800      8002729 :                   else if (!(mode & CLEANUP_CFGLAYOUT)
    2801              :                            /* If the jump insn has side effects,
    2802              :                               we can't kill the edge.  */
    2803      6788593 :                            && (!JUMP_P (BB_END (b))
    2804      2190465 :                                || (reload_completed
    2805      3017606 :                                    ? simplejump_p (BB_END (b))
    2806       827141 :                                    : (onlyjump_p (BB_END (b))
    2807       826327 :                                       && !tablejump_p (BB_END (b),
    2808              :                                                        NULL, NULL))))
    2809     17806935 :                            && (next = merge_blocks_move (s, b, c, mode)))
    2810              :                       {
    2811              :                         b = next;
    2812              :                         changed_here = true;
    2813              :                       }
    2814              :                 }
    2815              : 
    2816              :               /* Try to change a branch to a return to just that return.  */
    2817    393660377 :               rtx_insn *ret, *use;
    2818    393660377 :               if (single_succ_p (b)
    2819    170514928 :                   && onlyjump_p (BB_END (b))
    2820    420226053 :                   && bb_is_just_return (single_succ (b), &ret, &use))
    2821              :                 {
    2822        36760 :                   if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)),
    2823        36760 :                                      PATTERN (ret), 0))
    2824              :                     {
    2825        36760 :                       if (use)
    2826        21751 :                         emit_insn_before (copy_insn (PATTERN (use)),
    2827        21751 :                                           BB_END (b));
    2828        36760 :                       if (dump_file)
    2829           23 :                         fprintf (dump_file, "Changed jump %d->%d to return.\n",
    2830           23 :                                  b->index, single_succ (b)->index);
    2831        36760 :                       redirect_edge_succ (single_succ_edge (b),
    2832        36760 :                                           EXIT_BLOCK_PTR_FOR_FN (cfun));
    2833        36760 :                       single_succ_edge (b)->flags &= ~EDGE_CROSSING;
    2834        36760 :                       changed_here = true;
    2835              :                     }
    2836              :                 }
    2837              : 
    2838              :               /* Try to change a conditional branch to a return to the
    2839              :                  respective conditional return.  */
    2840    393660377 :               if (EDGE_COUNT (b->succs) == 2
    2841    206516853 :                   && any_condjump_p (BB_END (b))
    2842    574859135 :                   && bb_is_just_return (BRANCH_EDGE (b)->dest, &ret, &use))
    2843              :                 {
    2844       582500 :                   if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)),
    2845       582500 :                                      PATTERN (ret), 0))
    2846              :                     {
    2847            0 :                       if (use)
    2848            0 :                         emit_insn_before (copy_insn (PATTERN (use)),
    2849            0 :                                           BB_END (b));
    2850            0 :                       if (dump_file)
    2851            0 :                         fprintf (dump_file, "Changed conditional jump %d->%d "
    2852              :                                  "to conditional return.\n",
    2853            0 :                                  b->index, BRANCH_EDGE (b)->dest->index);
    2854            0 :                       redirect_edge_succ (BRANCH_EDGE (b),
    2855            0 :                                           EXIT_BLOCK_PTR_FOR_FN (cfun));
    2856            0 :                       BRANCH_EDGE (b)->flags &= ~EDGE_CROSSING;
    2857            0 :                       changed_here = true;
    2858              :                     }
    2859              :                 }
    2860              : 
    2861              :               /* Try to flip a conditional branch that falls through to
    2862              :                  a return so that it becomes a conditional return and a
    2863              :                  new jump to the original branch target.  */
    2864    393660377 :               if (EDGE_COUNT (b->succs) == 2
    2865    206516853 :                   && BRANCH_EDGE (b)->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
    2866    206516853 :                   && any_condjump_p (BB_END (b))
    2867    574859135 :                   && bb_is_just_return (FALLTHRU_EDGE (b)->dest, &ret, &use))
    2868              :                 {
    2869       160559 :                   if (invert_jump (as_a <rtx_jump_insn *> (BB_END (b)),
    2870       160559 :                                    JUMP_LABEL (BB_END (b)), 0))
    2871              :                     {
    2872       160559 :                       basic_block new_ft = BRANCH_EDGE (b)->dest;
    2873       160559 :                       if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)),
    2874       160559 :                                          PATTERN (ret), 0))
    2875              :                         {
    2876            0 :                           if (use)
    2877            0 :                             emit_insn_before (copy_insn (PATTERN (use)),
    2878            0 :                                               BB_END (b));
    2879            0 :                           if (dump_file)
    2880            0 :                             fprintf (dump_file, "Changed conditional jump "
    2881              :                                      "%d->%d to conditional return, adding "
    2882              :                                      "fall-through jump.\n",
    2883            0 :                                      b->index, BRANCH_EDGE (b)->dest->index);
    2884            0 :                           redirect_edge_succ (BRANCH_EDGE (b),
    2885            0 :                                               EXIT_BLOCK_PTR_FOR_FN (cfun));
    2886            0 :                           BRANCH_EDGE (b)->flags &= ~EDGE_CROSSING;
    2887            0 :                           std::swap (BRANCH_EDGE (b)->probability,
    2888            0 :                                      FALLTHRU_EDGE (b)->probability);
    2889            0 :                           update_br_prob_note (b);
    2890            0 :                           basic_block jb = force_nonfallthru (FALLTHRU_EDGE (b));
    2891            0 :                           notice_new_block (jb);
    2892            0 :                           if (!redirect_jump (as_a <rtx_jump_insn *> (BB_END (jb)),
    2893            0 :                                               block_label (new_ft), 0))
    2894            0 :                             gcc_unreachable ();
    2895            0 :                           redirect_edge_succ (single_succ_edge (jb), new_ft);
    2896            0 :                           changed_here = true;
    2897              :                         }
    2898              :                       else
    2899              :                         {
    2900              :                           /* Invert the jump back to what it was.  This should
    2901              :                              never fail.  */
    2902       160559 :                           if (!invert_jump (as_a <rtx_jump_insn *> (BB_END (b)),
    2903       160559 :                                             JUMP_LABEL (BB_END (b)), 0))
    2904            0 :                             gcc_unreachable ();
    2905              :                         }
    2906              :                     }
    2907              :                 }
    2908              : 
    2909              :               /* Simplify branch over branch.  */
    2910    393660377 :               if ((mode & CLEANUP_EXPENSIVE)
    2911    104051978 :                    && !(mode & CLEANUP_CFGLAYOUT)
    2912    427241983 :                    && try_simplify_condjump (b))
    2913              :                 changed_here = true;
    2914              : 
    2915              :               /* If B has a single outgoing edge, but uses a
    2916              :                  non-trivial jump instruction without side-effects, we
    2917              :                  can either delete the jump entirely, or replace it
    2918              :                  with a simple unconditional jump.  */
    2919    393660377 :               if (single_succ_p (b)
    2920    170514964 :                   && single_succ (b) != EXIT_BLOCK_PTR_FOR_FN (cfun)
    2921    140832189 :                   && onlyjump_p (BB_END (b))
    2922     28244787 :                   && !CROSSING_JUMP_P (BB_END (b))
    2923    419137525 :                   && try_redirect_by_replacing_jump (single_succ_edge (b),
    2924              :                                                      single_succ (b),
    2925     27193625 :                                                      (mode & CLEANUP_CFGLAYOUT) != 0))
    2926              :                 {
    2927      4158432 :                   update_forwarder_flag (b);
    2928      4158432 :                   changed_here = true;
    2929              :                 }
    2930              : 
    2931              :               /* Simplify branch to branch.  */
    2932    393660377 :               if (try_forward_edges (mode, b))
    2933              :                 {
    2934      6283639 :                   update_forwarder_flag (b);
    2935      6283639 :                   changed_here = true;
    2936              :                 }
    2937              : 
    2938              :               /* Look for shared code between blocks.  */
    2939    393660377 :               if ((mode & CLEANUP_CROSSJUMP)
    2940    393660377 :                   && try_crossjump_bb (mode, b))
    2941              :                 changed_here = true;
    2942              : 
    2943    393660377 :               if ((mode & CLEANUP_CROSSJUMP)
    2944              :                   /* This can lengthen register lifetimes.  Do it only after
    2945              :                      reload.  */
    2946     28594069 :                   && reload_completed
    2947    422254446 :                   && try_head_merge_bb (b))
    2948              :                 changed_here = true;
    2949              : 
    2950              :               /* Don't get confused by the index shift caused by
    2951              :                  deleting blocks.  */
    2952    393623127 :               if (!changed_here)
    2953    379088952 :                 b = b->next_bb;
    2954              :               else
    2955              :                 changed = true;
    2956              :             }
    2957              : 
    2958     25649652 :           if ((mode & CLEANUP_CROSSJUMP)
    2959     25649652 :               && try_crossjump_bb (mode, EXIT_BLOCK_PTR_FOR_FN (cfun)))
    2960              :             changed = true;
    2961              : 
    2962     25649652 :           if (block_was_dirty)
    2963              :             {
    2964              :               /* This should only be set by head-merging.  */
    2965       194688 :               gcc_assert (mode & CLEANUP_CROSSJUMP);
    2966       194688 :               df_analyze ();
    2967              :             }
    2968              : 
    2969     25649652 :           if (changed)
    2970              :             {
    2971              :               /* Edge forwarding in particular can cause hot blocks previously
    2972              :                  reached by both hot and cold blocks to become dominated only
    2973              :                  by cold blocks. This will cause the verification below to fail,
    2974              :                  and lead to now cold code in the hot section. This is not easy
    2975              :                  to detect and fix during edge forwarding, and in some cases
    2976              :                  is only visible after newly unreachable blocks are deleted,
    2977              :                  which will be done in fixup_partitions.  */
    2978      3835987 :               if ((mode & CLEANUP_NO_PARTITIONING) == 0)
    2979              :                 {
    2980      3699277 :                   fixup_partitions ();
    2981      3699277 :                   checking_verify_flow_info ();
    2982              :                 }
    2983              :             }
    2984              : 
    2985     25649652 :           changed_overall |= changed;
    2986     25649652 :           first_pass = false;
    2987              :         }
    2988              :       while (changed);
    2989              :     }
    2990              : 
    2991    347675845 :   FOR_ALL_BB_FN (b, cfun)
    2992    325862180 :     b->flags &= ~(BB_FORWARDER_BLOCK | BB_NONTHREADABLE_BLOCK);
    2993              : 
    2994     21813665 :   return changed_overall;
    2995              : }
    2996              : 
    2997              : /* Delete all unreachable basic blocks.  */
    2998              : 
    2999              : bool
    3000     28154679 : delete_unreachable_blocks (void)
    3001              : {
    3002     28154679 :   bool changed = false;
    3003     28154679 :   basic_block b, prev_bb;
    3004              : 
    3005     28154679 :   find_unreachable_blocks ();
    3006              : 
    3007              :   /* When we're in GIMPLE mode and there may be debug bind insns, we
    3008              :      should delete blocks in reverse dominator order, so as to get a
    3009              :      chance to substitute all released DEFs into debug bind stmts.  If
    3010              :      we don't have dominators information, walking blocks backward
    3011              :      gets us a better chance of retaining most debug information than
    3012              :      otherwise.  */
    3013     12553109 :   if (MAY_HAVE_DEBUG_BIND_INSNS && current_ir_type () == IR_GIMPLE
    3014     28411904 :       && dom_info_available_p (CDI_DOMINATORS))
    3015              :     {
    3016            0 :       for (b = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
    3017            0 :            b != ENTRY_BLOCK_PTR_FOR_FN (cfun); b = prev_bb)
    3018              :         {
    3019            0 :           prev_bb = b->prev_bb;
    3020              : 
    3021            0 :           if (!(b->flags & BB_REACHABLE))
    3022              :             {
    3023              :               /* Speed up the removal of blocks that don't dominate
    3024              :                  others.  Walking backwards, this should be the common
    3025              :                  case.  */
    3026            0 :               if (!first_dom_son (CDI_DOMINATORS, b))
    3027            0 :                 delete_basic_block (b);
    3028              :               else
    3029              :                 {
    3030            0 :                   auto_vec<basic_block> h
    3031            0 :                     = get_all_dominated_blocks (CDI_DOMINATORS, b);
    3032              : 
    3033            0 :                   while (h.length ())
    3034              :                     {
    3035            0 :                       b = h.pop ();
    3036              : 
    3037            0 :                       prev_bb = b->prev_bb;
    3038              : 
    3039            0 :                       gcc_assert (!(b->flags & BB_REACHABLE));
    3040              : 
    3041            0 :                       delete_basic_block (b);
    3042              :                     }
    3043            0 :                 }
    3044              : 
    3045              :               changed = true;
    3046              :             }
    3047              :         }
    3048              :     }
    3049              :   else
    3050              :     {
    3051     28154679 :       for (b = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
    3052    411479847 :            b != ENTRY_BLOCK_PTR_FOR_FN (cfun); b = prev_bb)
    3053              :         {
    3054    383325168 :           prev_bb = b->prev_bb;
    3055              : 
    3056    383325168 :           if (!(b->flags & BB_REACHABLE))
    3057              :             {
    3058      1609800 :               delete_basic_block (b);
    3059      1609800 :               changed = true;
    3060              :             }
    3061              :         }
    3062              :     }
    3063              : 
    3064     28154679 :   if (changed)
    3065       442579 :     tidy_fallthru_edges ();
    3066     28154679 :   return changed;
    3067              : }
    3068              : 
    3069              : /* Delete any jump tables never referenced.  We can't delete them at the
    3070              :    time of removing tablejump insn as they are referenced by the preceding
    3071              :    insns computing the destination, so we delay deleting and garbagecollect
    3072              :    them once life information is computed.  */
    3073              : void
    3074      9158261 : delete_dead_jumptables (void)
    3075              : {
    3076      9158261 :   basic_block bb;
    3077              : 
    3078              :   /* A dead jump table does not belong to any basic block.  Scan insns
    3079              :      between two adjacent basic blocks.  */
    3080    100689193 :   FOR_EACH_BB_FN (bb, cfun)
    3081              :     {
    3082     91530932 :       rtx_insn *insn, *next;
    3083              : 
    3084     91530932 :       for (insn = NEXT_INSN (BB_END (bb));
    3085    167221100 :            insn && !NOTE_INSN_BASIC_BLOCK_P (insn);
    3086              :            insn = next)
    3087              :         {
    3088     75690168 :           next = NEXT_INSN (insn);
    3089     75690168 :           if (LABEL_P (insn)
    3090     42879961 :               && LABEL_NUSES (insn) == LABEL_PRESERVE_P (insn)
    3091     77500178 :               && JUMP_TABLE_DATA_P (next))
    3092              :             {
    3093            0 :               rtx_insn *label = insn, *jump = next;
    3094              : 
    3095            0 :               if (dump_file)
    3096            0 :                 fprintf (dump_file, "Dead jumptable %i removed\n",
    3097            0 :                          INSN_UID (insn));
    3098              : 
    3099            0 :               next = NEXT_INSN (next);
    3100            0 :               delete_insn (jump);
    3101            0 :               delete_insn (label);
    3102              :             }
    3103              :         }
    3104              :     }
    3105      9158261 : }
    3106              : 
    3107              : 
    3108              : /* Tidy the CFG by deleting unreachable code and whatnot.  */
    3109              : 
    3110              : bool
    3111     19662450 : cleanup_cfg (int mode)
    3112              : {
    3113     19662450 :   bool changed = false;
    3114              : 
    3115              :   /* Set the cfglayout mode flag here.  We could update all the callers
    3116              :      but that is just inconvenient, especially given that we eventually
    3117              :      want to have cfglayout mode as the default.  */
    3118     19662450 :   if (current_ir_type () == IR_RTL_CFGLAYOUT)
    3119     13034639 :     mode |= CLEANUP_CFGLAYOUT;
    3120              : 
    3121     19662450 :   timevar_push (TV_CLEANUP_CFG);
    3122     19662450 :   if (delete_unreachable_blocks ())
    3123              :     {
    3124       151987 :       changed = true;
    3125              :       /* We've possibly created trivially dead code.  Cleanup it right
    3126              :          now to introduce more opportunities for try_optimize_cfg.  */
    3127       151987 :       if (!(mode & (CLEANUP_NO_INSN_DEL))
    3128        41605 :           && !reload_completed)
    3129        41523 :         delete_trivially_dead_insns (get_insns (), max_reg_num ());
    3130              :     }
    3131              : 
    3132     19662450 :   compact_blocks ();
    3133              : 
    3134              :   /* To tail-merge blocks ending in the same noreturn function (e.g.
    3135              :      a call to abort) we have to insert fake edges to exit.  Do this
    3136              :      here once.  The fake edges do not interfere with any other CFG
    3137              :      cleanups.  */
    3138     19662450 :   if (mode & CLEANUP_CROSSJUMP)
    3139       961304 :     add_noreturn_fake_exit_edges ();
    3140              : 
    3141     19662450 :   if (!dbg_cnt (cfg_cleanup))
    3142              :     return changed;
    3143              : 
    3144     21813665 :   while (try_optimize_cfg (mode))
    3145              :     {
    3146      3749118 :       delete_unreachable_blocks (), changed = true;
    3147      3749118 :       if (!(mode & CLEANUP_NO_INSN_DEL))
    3148              :         {
    3149              :           /* Try to remove some trivially dead insns when doing an expensive
    3150              :              cleanup.  But delete_trivially_dead_insns doesn't work after
    3151              :              reload (it only handles pseudos) and run_fast_dce is too costly
    3152              :              to run in every iteration.
    3153              : 
    3154              :              For effective cross jumping, we really want to run a fast DCE to
    3155              :              clean up any dead conditions, or they get in the way of performing
    3156              :              useful tail merges.
    3157              : 
    3158              :              Other transformations in cleanup_cfg are not so sensitive to dead
    3159              :              code, so delete_trivially_dead_insns or even doing nothing at all
    3160              :              is good enough.  */
    3161       631799 :           if ((mode & CLEANUP_EXPENSIVE) && !reload_completed
    3162      2216690 :               && !delete_trivially_dead_insns (get_insns (), max_reg_num ()))
    3163              :             break;
    3164      2151215 :           if ((mode & CLEANUP_CROSSJUMP) && crossjumps_occurred)
    3165              :             {
    3166        79038 :               run_fast_dce ();
    3167        79038 :               mode &= ~CLEANUP_FORCE_FAST_DCE;
    3168              :             }
    3169              :         }
    3170              :       else
    3171              :         break;
    3172              :     }
    3173              : 
    3174     19662450 :   if (mode & CLEANUP_CROSSJUMP)
    3175       961304 :     remove_fake_exit_edges ();
    3176              : 
    3177     19662450 :   if (mode & CLEANUP_FORCE_FAST_DCE)
    3178       114961 :     run_fast_dce ();
    3179              : 
    3180              :   /* Don't call delete_dead_jumptables in cfglayout mode, because
    3181              :      that function assumes that jump tables are in the insns stream.
    3182              :      But we also don't _have_ to delete dead jumptables in cfglayout
    3183              :      mode because we shouldn't even be looking at things that are
    3184              :      not in a basic block.  Dead jumptables are cleaned up when
    3185              :      going out of cfglayout mode.  */
    3186     19662450 :   if (!(mode & CLEANUP_CFGLAYOUT))
    3187      6627811 :     delete_dead_jumptables ();
    3188              : 
    3189              :   /* ???  We probably do this way too often.  */
    3190     19662450 :   if (current_loops
    3191      9166543 :       && (changed
    3192      6764839 :           || (mode & CLEANUP_CFG_CHANGED)))
    3193              :     {
    3194      2492943 :       timevar_push (TV_REPAIR_LOOPS);
    3195              :       /* The above doesn't preserve dominance info if available.  */
    3196      2492943 :       gcc_assert (!dom_info_available_p (CDI_DOMINATORS));
    3197      2492943 :       calculate_dominance_info (CDI_DOMINATORS);
    3198      2492943 :       fix_loop_structure (NULL);
    3199      2492943 :       free_dominance_info (CDI_DOMINATORS);
    3200      2492943 :       timevar_pop (TV_REPAIR_LOOPS);
    3201              :     }
    3202              : 
    3203     19662450 :   timevar_pop (TV_CLEANUP_CFG);
    3204              : 
    3205     19662450 :   return changed;
    3206              : }
    3207              : 
    3208              : namespace {
    3209              : 
    3210              : const pass_data pass_data_jump =
    3211              : {
    3212              :   RTL_PASS, /* type */
    3213              :   "jump", /* name */
    3214              :   OPTGROUP_NONE, /* optinfo_flags */
    3215              :   TV_JUMP, /* tv_id */
    3216              :   0, /* properties_required */
    3217              :   0, /* properties_provided */
    3218              :   0, /* properties_destroyed */
    3219              :   0, /* todo_flags_start */
    3220              :   0, /* todo_flags_finish */
    3221              : };
    3222              : 
    3223              : class pass_jump : public rtl_opt_pass
    3224              : {
    3225              : public:
    3226       298828 :   pass_jump (gcc::context *ctxt)
    3227       597656 :     : rtl_opt_pass (pass_data_jump, ctxt)
    3228              :   {}
    3229              : 
    3230              :   /* opt_pass methods: */
    3231              :   unsigned int execute (function *) final override;
    3232              : 
    3233              : }; // class pass_jump
    3234              : 
    3235              : unsigned int
    3236      1488367 : pass_jump::execute (function *)
    3237              : {
    3238      1488367 :   delete_trivially_dead_insns (get_insns (), max_reg_num ());
    3239      1488367 :   if (dump_file)
    3240           84 :     dump_flow_info (dump_file, dump_flags);
    3241      2976734 :   cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0)
    3242      1041650 :                | (flag_thread_jumps && flag_expensive_optimizations
    3243      1488367 :                   ? CLEANUP_THREADING : 0));
    3244      1488367 :   return 0;
    3245              : }
    3246              : 
    3247              : } // anon namespace
    3248              : 
    3249              : rtl_opt_pass *
    3250       298828 : make_pass_jump (gcc::context *ctxt)
    3251              : {
    3252       298828 :   return new pass_jump (ctxt);
    3253              : }
    3254              : 
    3255              : namespace {
    3256              : 
    3257              : const pass_data pass_data_jump_after_combine =
    3258              : {
    3259              :   RTL_PASS, /* type */
    3260              :   "jump_after_combine", /* name */
    3261              :   OPTGROUP_NONE, /* optinfo_flags */
    3262              :   TV_JUMP, /* tv_id */
    3263              :   0, /* properties_required */
    3264              :   0, /* properties_provided */
    3265              :   0, /* properties_destroyed */
    3266              :   0, /* todo_flags_start */
    3267              :   0, /* todo_flags_finish */
    3268              : };
    3269              : 
    3270              : class pass_jump_after_combine : public rtl_opt_pass
    3271              : {
    3272              : public:
    3273       298828 :   pass_jump_after_combine (gcc::context *ctxt)
    3274       597656 :     : rtl_opt_pass (pass_data_jump_after_combine, ctxt)
    3275              :   {}
    3276              : 
    3277              :   /* opt_pass methods: */
    3278      1488378 :   bool gate (function *) final override
    3279              :   {
    3280      1488378 :     return flag_thread_jumps && flag_expensive_optimizations;
    3281              :   }
    3282              :   unsigned int execute (function *) final override;
    3283              : 
    3284              : }; // class pass_jump_after_combine
    3285              : 
    3286              : unsigned int
    3287       961159 : pass_jump_after_combine::execute (function *)
    3288              : {
    3289              :   /* Jump threading does not keep dominators up-to-date.  */
    3290       961159 :   free_dominance_info (CDI_DOMINATORS);
    3291       961159 :   cleanup_cfg (CLEANUP_THREADING);
    3292       961159 :   return 0;
    3293              : }
    3294              : 
    3295              : } // anon namespace
    3296              : 
    3297              : rtl_opt_pass *
    3298       298828 : make_pass_jump_after_combine (gcc::context *ctxt)
    3299              : {
    3300       298828 :   return new pass_jump_after_combine (ctxt);
    3301              : }
    3302              : 
    3303              : namespace {
    3304              : 
    3305              : const pass_data pass_data_jump2 =
    3306              : {
    3307              :   RTL_PASS, /* type */
    3308              :   "jump2", /* name */
    3309              :   OPTGROUP_NONE, /* optinfo_flags */
    3310              :   TV_JUMP, /* tv_id */
    3311              :   0, /* properties_required */
    3312              :   0, /* properties_provided */
    3313              :   0, /* properties_destroyed */
    3314              :   0, /* todo_flags_start */
    3315              :   0, /* todo_flags_finish */
    3316              : };
    3317              : 
    3318              : class pass_jump2 : public rtl_opt_pass
    3319              : {
    3320              : public:
    3321       298828 :   pass_jump2 (gcc::context *ctxt)
    3322       597656 :     : rtl_opt_pass (pass_data_jump2, ctxt)
    3323              :   {}
    3324              : 
    3325              :   /* opt_pass methods: */
    3326      1488371 :   unsigned int execute (function *) final override
    3327              :     {
    3328      2015438 :       cleanup_cfg (flag_crossjumping ? CLEANUP_CROSSJUMP : 0);
    3329      1488371 :       return 0;
    3330              :     }
    3331              : 
    3332              : }; // class pass_jump2
    3333              : 
    3334              : } // anon namespace
    3335              : 
    3336              : rtl_opt_pass *
    3337       298828 : make_pass_jump2 (gcc::context *ctxt)
    3338              : {
    3339       298828 :   return new pass_jump2 (ctxt);
    3340              : }
        

Generated by: LCOV version 2.4-beta

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