Home | History | Annotate | Line # | Download | only in gcc
gimple-ssa-split-paths.cc revision 1.1
      1  1.1  mrg /* Support routines for Splitting Paths to loop backedges
      2  1.1  mrg    Copyright (C) 2015-2022 Free Software Foundation, Inc.
      3  1.1  mrg    Contributed by Ajit Kumar Agarwal <ajitkum (at) xilinx.com>.
      4  1.1  mrg 
      5  1.1  mrg  This file is part of GCC.
      6  1.1  mrg 
      7  1.1  mrg  GCC is free software; you can redistribute it and/or modify
      8  1.1  mrg  it under the terms of the GNU General Public License as published by
      9  1.1  mrg  the Free Software Foundation; either version 3, or (at your option)
     10  1.1  mrg  any later version.
     11  1.1  mrg 
     12  1.1  mrg GCC is distributed in the hope that it will be useful,
     13  1.1  mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  mrg GNU General Public License for more details.
     16  1.1  mrg 
     17  1.1  mrg You should have received a copy of the GNU General Public License
     18  1.1  mrg along with GCC; see the file COPYING3.  If not see
     19  1.1  mrg <http://www.gnu.org/licenses/>.  */
     20  1.1  mrg 
     21  1.1  mrg #include "config.h"
     22  1.1  mrg #include "system.h"
     23  1.1  mrg #include "coretypes.h"
     24  1.1  mrg #include "backend.h"
     25  1.1  mrg #include "tree.h"
     26  1.1  mrg #include "gimple.h"
     27  1.1  mrg #include "tree-pass.h"
     28  1.1  mrg #include "tree-cfg.h"
     29  1.1  mrg #include "cfganal.h"
     30  1.1  mrg #include "cfgloop.h"
     31  1.1  mrg #include "gimple-iterator.h"
     32  1.1  mrg #include "tracer.h"
     33  1.1  mrg #include "predict.h"
     34  1.1  mrg #include "gimple-ssa.h"
     35  1.1  mrg #include "tree-phinodes.h"
     36  1.1  mrg #include "ssa-iterators.h"
     37  1.1  mrg #include "fold-const.h"
     38  1.1  mrg 
     39  1.1  mrg /* Given LATCH, the latch block in a loop, see if the shape of the
     40  1.1  mrg    path reaching LATCH is suitable for being split by duplication.
     41  1.1  mrg    If so, return the block that will be duplicated into its predecessor
     42  1.1  mrg    paths.  Else return NULL.  */
     43  1.1  mrg 
     44  1.1  mrg static basic_block
     45  1.1  mrg find_block_to_duplicate_for_splitting_paths (basic_block latch)
     46  1.1  mrg {
     47  1.1  mrg   /* We should have simple latches at this point.  So the latch should
     48  1.1  mrg      have a single successor.  This implies the predecessor of the latch
     49  1.1  mrg      likely has the loop exit.  And it's that predecessor we're most
     50  1.1  mrg      interested in. To keep things simple, we're going to require that
     51  1.1  mrg      the latch have a single predecessor too.  */
     52  1.1  mrg   if (single_succ_p (latch) && single_pred_p (latch))
     53  1.1  mrg     {
     54  1.1  mrg       basic_block bb = get_immediate_dominator (CDI_DOMINATORS, latch);
     55  1.1  mrg       gcc_assert (single_pred_edge (latch)->src == bb);
     56  1.1  mrg 
     57  1.1  mrg       /* If BB has been marked as not to be duplicated, then honor that
     58  1.1  mrg 	 request.  */
     59  1.1  mrg       if (ignore_bb_p (bb))
     60  1.1  mrg 	return NULL;
     61  1.1  mrg 
     62  1.1  mrg       gimple *last = gsi_stmt (gsi_last_nondebug_bb (bb));
     63  1.1  mrg       /* The immediate dominator of the latch must end in a conditional.  */
     64  1.1  mrg       if (!last || gimple_code (last) != GIMPLE_COND)
     65  1.1  mrg 	return NULL;
     66  1.1  mrg 
     67  1.1  mrg       /* We're hoping that BB is a join point for an IF-THEN-ELSE diamond
     68  1.1  mrg 	 region.  Verify that it is.
     69  1.1  mrg 
     70  1.1  mrg 	 First, verify that BB has two predecessors (each arm of the
     71  1.1  mrg 	 IF-THEN-ELSE) and two successors (the latch and exit) and that
     72  1.1  mrg 	 all edges are normal.  */
     73  1.1  mrg       if (EDGE_COUNT (bb->preds) == 2
     74  1.1  mrg 	  && !(EDGE_PRED (bb, 0)->flags & EDGE_COMPLEX)
     75  1.1  mrg 	  && !(EDGE_PRED (bb, 1)->flags & EDGE_COMPLEX)
     76  1.1  mrg 	  && EDGE_COUNT (bb->succs) == 2
     77  1.1  mrg 	  && !(EDGE_SUCC (bb, 0)->flags & EDGE_COMPLEX)
     78  1.1  mrg 	  && !(EDGE_SUCC (bb, 1)->flags & EDGE_COMPLEX))
     79  1.1  mrg 	{
     80  1.1  mrg 	  /* Now verify that BB's immediate dominator ends in a
     81  1.1  mrg 	     conditional as well.  */
     82  1.1  mrg 	  basic_block bb_idom = get_immediate_dominator (CDI_DOMINATORS, bb);
     83  1.1  mrg 	  gimple *last = gsi_stmt (gsi_last_nondebug_bb (bb_idom));
     84  1.1  mrg 	  if (!last || gimple_code (last) != GIMPLE_COND)
     85  1.1  mrg 	    return NULL;
     86  1.1  mrg 
     87  1.1  mrg 	  /* And that BB's immediate dominator's successors are the
     88  1.1  mrg 	     predecessors of BB or BB itself.  */
     89  1.1  mrg 	  if (!(EDGE_PRED (bb, 0)->src == bb_idom
     90  1.1  mrg 		|| find_edge (bb_idom, EDGE_PRED (bb, 0)->src))
     91  1.1  mrg 	      || !(EDGE_PRED (bb, 1)->src == bb_idom
     92  1.1  mrg 		   || find_edge (bb_idom, EDGE_PRED (bb, 1)->src)))
     93  1.1  mrg 	    return NULL;
     94  1.1  mrg 
     95  1.1  mrg 	  /* And that the predecessors of BB each have a single successor
     96  1.1  mrg 	     or are BB's immediate domiator itself.  */
     97  1.1  mrg 	  if (!(EDGE_PRED (bb, 0)->src == bb_idom
     98  1.1  mrg 		|| single_succ_p (EDGE_PRED (bb, 0)->src))
     99  1.1  mrg 	      || !(EDGE_PRED (bb, 1)->src == bb_idom
    100  1.1  mrg 		   || single_succ_p (EDGE_PRED (bb, 1)->src)))
    101  1.1  mrg 	    return NULL;
    102  1.1  mrg 
    103  1.1  mrg 	  /* So at this point we have a simple diamond for an IF-THEN-ELSE
    104  1.1  mrg 	     construct starting at BB_IDOM, with a join point at BB.  BB
    105  1.1  mrg 	     pass control outside the loop or to the loop latch.
    106  1.1  mrg 
    107  1.1  mrg 	     We're going to want to create two duplicates of BB, one for
    108  1.1  mrg 	     each successor of BB_IDOM.  */
    109  1.1  mrg 	  return bb;
    110  1.1  mrg 	}
    111  1.1  mrg     }
    112  1.1  mrg   return NULL;
    113  1.1  mrg }
    114  1.1  mrg 
    115  1.1  mrg /* Return the number of non-debug statements in a block.  */
    116  1.1  mrg static unsigned int
    117  1.1  mrg count_stmts_in_block (basic_block bb)
    118  1.1  mrg {
    119  1.1  mrg   gimple_stmt_iterator gsi;
    120  1.1  mrg   unsigned int num_stmts = 0;
    121  1.1  mrg 
    122  1.1  mrg   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    123  1.1  mrg     {
    124  1.1  mrg       gimple *stmt = gsi_stmt (gsi);
    125  1.1  mrg       if (!is_gimple_debug (stmt))
    126  1.1  mrg 	num_stmts++;
    127  1.1  mrg     }
    128  1.1  mrg   return num_stmts;
    129  1.1  mrg }
    130  1.1  mrg 
    131  1.1  mrg /* Return TRUE if CODE represents a tree code that is not likely to
    132  1.1  mrg    be easily if-convertable because it likely expands into multiple
    133  1.1  mrg    insns, FALSE otherwise.  */
    134  1.1  mrg static bool
    135  1.1  mrg poor_ifcvt_candidate_code (enum tree_code code)
    136  1.1  mrg {
    137  1.1  mrg   return (code == MIN_EXPR
    138  1.1  mrg 	  || code == MAX_EXPR
    139  1.1  mrg 	  || code == ABS_EXPR
    140  1.1  mrg 	  || code == COND_EXPR
    141  1.1  mrg 	  || code == CALL_EXPR);
    142  1.1  mrg }
    143  1.1  mrg 
    144  1.1  mrg /* Return TRUE if BB is a reasonable block to duplicate by examining
    145  1.1  mrg    its size, false otherwise.  BB will always be a loop latch block.
    146  1.1  mrg 
    147  1.1  mrg    Things to consider:
    148  1.1  mrg 
    149  1.1  mrg      We do not want to spoil if-conversion if at all possible.
    150  1.1  mrg 
    151  1.1  mrg      Most of the benefit seems to be from eliminating the unconditional
    152  1.1  mrg      jump rather than CSE/DCE opportunities.  So favor duplicating
    153  1.1  mrg      small latches.  A latch with just a conditional branch is ideal.
    154  1.1  mrg 
    155  1.1  mrg      CSE/DCE opportunties crop up when statements from the predecessors
    156  1.1  mrg      feed statements in the latch and allow statements in the latch to
    157  1.1  mrg      simplify.  */
    158  1.1  mrg 
    159  1.1  mrg static bool
    160  1.1  mrg is_feasible_trace (basic_block bb)
    161  1.1  mrg {
    162  1.1  mrg   basic_block pred1 = EDGE_PRED (bb, 0)->src;
    163  1.1  mrg   basic_block pred2 = EDGE_PRED (bb, 1)->src;
    164  1.1  mrg   int num_stmts_in_join = count_stmts_in_block (bb);
    165  1.1  mrg   int num_stmts_in_pred1
    166  1.1  mrg     = EDGE_COUNT (pred1->succs) == 1 ? count_stmts_in_block (pred1) : 0;
    167  1.1  mrg   int num_stmts_in_pred2
    168  1.1  mrg     = EDGE_COUNT (pred2->succs) == 1 ? count_stmts_in_block (pred2) : 0;
    169  1.1  mrg 
    170  1.1  mrg   /* This is meant to catch cases that are likely opportunities for
    171  1.1  mrg      if-conversion.  Essentially we look for the case where
    172  1.1  mrg      BB's predecessors are both single statement blocks where
    173  1.1  mrg      the output of that statement feed the same PHI in BB.  */
    174  1.1  mrg   if (num_stmts_in_pred1 == 1 && num_stmts_in_pred2 == 1)
    175  1.1  mrg     {
    176  1.1  mrg       gimple *stmt1 = last_and_only_stmt (pred1);
    177  1.1  mrg       gimple *stmt2 = last_and_only_stmt (pred2);
    178  1.1  mrg 
    179  1.1  mrg       if (stmt1 && stmt2
    180  1.1  mrg 	  && gimple_code (stmt1) == GIMPLE_ASSIGN
    181  1.1  mrg 	  && gimple_code (stmt2) == GIMPLE_ASSIGN)
    182  1.1  mrg 	{
    183  1.1  mrg 	  enum tree_code code1 = gimple_assign_rhs_code (stmt1);
    184  1.1  mrg 	  enum tree_code code2 = gimple_assign_rhs_code (stmt2);
    185  1.1  mrg 
    186  1.1  mrg 	  if (!poor_ifcvt_candidate_code (code1)
    187  1.1  mrg 	      && !poor_ifcvt_candidate_code (code2))
    188  1.1  mrg 	    {
    189  1.1  mrg 	      tree lhs1 = gimple_assign_lhs (stmt1);
    190  1.1  mrg 	      tree lhs2 = gimple_assign_lhs (stmt2);
    191  1.1  mrg 	      gimple_stmt_iterator gsi;
    192  1.1  mrg 	      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    193  1.1  mrg 		{
    194  1.1  mrg 		  gimple *phi = gsi_stmt (gsi);
    195  1.1  mrg 		  if ((gimple_phi_arg_def (phi, 0) == lhs1
    196  1.1  mrg 		       && gimple_phi_arg_def (phi, 1) == lhs2)
    197  1.1  mrg 		      || (gimple_phi_arg_def (phi, 1) == lhs1
    198  1.1  mrg 			  && gimple_phi_arg_def (phi, 0) == lhs2))
    199  1.1  mrg 		    {
    200  1.1  mrg 		      if (dump_file && (dump_flags & TDF_DETAILS))
    201  1.1  mrg 			fprintf (dump_file,
    202  1.1  mrg 				 "Block %d appears to be a join point for "
    203  1.1  mrg 				 "if-convertable diamond.\n",
    204  1.1  mrg 				 bb->index);
    205  1.1  mrg 		      return false;
    206  1.1  mrg 		    }
    207  1.1  mrg 		}
    208  1.1  mrg 	    }
    209  1.1  mrg 	}
    210  1.1  mrg     }
    211  1.1  mrg 
    212  1.1  mrg   /* Canonicalize the form.  */
    213  1.1  mrg   if (num_stmts_in_pred1 == 0 && num_stmts_in_pred2 == 1)
    214  1.1  mrg     {
    215  1.1  mrg       std::swap (pred1, pred2);
    216  1.1  mrg       std::swap (num_stmts_in_pred1, num_stmts_in_pred2);
    217  1.1  mrg     }
    218  1.1  mrg 
    219  1.1  mrg   /* Another variant.  This one is half-diamond.  */
    220  1.1  mrg   if (num_stmts_in_pred1 == 1 && num_stmts_in_pred2 == 0
    221  1.1  mrg       && dominated_by_p (CDI_DOMINATORS, pred1, pred2))
    222  1.1  mrg     {
    223  1.1  mrg       gimple *stmt1 = last_and_only_stmt (pred1);
    224  1.1  mrg 
    225  1.1  mrg       /* The only statement in PRED1 must be an assignment that is
    226  1.1  mrg 	 not a good candidate for if-conversion.   This may need some
    227  1.1  mrg 	 generalization.  */
    228  1.1  mrg       if (stmt1 && gimple_code (stmt1) == GIMPLE_ASSIGN)
    229  1.1  mrg 	{
    230  1.1  mrg 	  enum tree_code code1 = gimple_assign_rhs_code (stmt1);
    231  1.1  mrg 
    232  1.1  mrg 	  if (!poor_ifcvt_candidate_code (code1))
    233  1.1  mrg 	    {
    234  1.1  mrg 	      tree lhs1 = gimple_assign_lhs (stmt1);
    235  1.1  mrg 	      tree rhs1 = gimple_assign_rhs1 (stmt1);
    236  1.1  mrg 
    237  1.1  mrg 	      gimple_stmt_iterator gsi;
    238  1.1  mrg 	      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    239  1.1  mrg 		{
    240  1.1  mrg 		  gimple *phi = gsi_stmt (gsi);
    241  1.1  mrg 		  if ((gimple_phi_arg_def (phi, 0) == lhs1
    242  1.1  mrg 		       && gimple_phi_arg_def (phi, 1) == rhs1)
    243  1.1  mrg 		      || (gimple_phi_arg_def (phi, 1) == lhs1
    244  1.1  mrg 			  && gimple_phi_arg_def (phi, 0) == rhs1))
    245  1.1  mrg 		    {
    246  1.1  mrg 		      if (dump_file && (dump_flags & TDF_DETAILS))
    247  1.1  mrg 			fprintf (dump_file,
    248  1.1  mrg 				 "Block %d appears to be a join point for "
    249  1.1  mrg 				 "if-convertable half-diamond.\n",
    250  1.1  mrg 				 bb->index);
    251  1.1  mrg 		      return false;
    252  1.1  mrg 		    }
    253  1.1  mrg 		}
    254  1.1  mrg 	    }
    255  1.1  mrg 	}
    256  1.1  mrg     }
    257  1.1  mrg 
    258  1.1  mrg   /* Canonicalize the form.  */
    259  1.1  mrg   if (single_pred_p (pred1) && single_pred (pred1) == pred2
    260  1.1  mrg       && num_stmts_in_pred1 == 0)
    261  1.1  mrg     std::swap (pred1, pred2);
    262  1.1  mrg 
    263  1.1  mrg   /* This is meant to catch another kind of cases that are likely opportunities
    264  1.1  mrg      for if-conversion.  After canonicalizing, PRED2 must be an empty block and
    265  1.1  mrg      PRED1 must be the only predecessor of PRED2.  Moreover, PRED1 is supposed
    266  1.1  mrg      to end with a cond_stmt which has the same args with the PHI in BB.  */
    267  1.1  mrg   if (single_pred_p (pred2) && single_pred (pred2) == pred1
    268  1.1  mrg       && num_stmts_in_pred2 == 0)
    269  1.1  mrg     {
    270  1.1  mrg       gimple *cond_stmt = last_stmt (pred1);
    271  1.1  mrg       if (cond_stmt && gimple_code (cond_stmt) == GIMPLE_COND)
    272  1.1  mrg 	{
    273  1.1  mrg 	  tree lhs = gimple_cond_lhs (cond_stmt);
    274  1.1  mrg 	  tree rhs = gimple_cond_rhs (cond_stmt);
    275  1.1  mrg 
    276  1.1  mrg 	  gimple_stmt_iterator gsi;
    277  1.1  mrg 	  for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    278  1.1  mrg 	    {
    279  1.1  mrg 	      gimple *phi = gsi_stmt (gsi);
    280  1.1  mrg 	      if ((operand_equal_p (gimple_phi_arg_def (phi, 0), lhs)
    281  1.1  mrg 		   && operand_equal_p (gimple_phi_arg_def (phi, 1), rhs))
    282  1.1  mrg 		  || (operand_equal_p (gimple_phi_arg_def (phi, 0), rhs)
    283  1.1  mrg 		      && (operand_equal_p (gimple_phi_arg_def (phi, 1), lhs))))
    284  1.1  mrg 		{
    285  1.1  mrg 		  if (dump_file && (dump_flags & TDF_DETAILS))
    286  1.1  mrg 		    fprintf (dump_file,
    287  1.1  mrg 			     "Block %d appears to be optimized to a join "
    288  1.1  mrg 			     "point for if-convertable half-diamond.\n",
    289  1.1  mrg 			     bb->index);
    290  1.1  mrg 		  return false;
    291  1.1  mrg 		}
    292  1.1  mrg 	    }
    293  1.1  mrg 	}
    294  1.1  mrg     }
    295  1.1  mrg 
    296  1.1  mrg   /* If the joiner has no PHIs with useful uses there is zero chance
    297  1.1  mrg      of CSE/DCE/jump-threading possibilities exposed by duplicating it.  */
    298  1.1  mrg   bool found_useful_phi = false;
    299  1.1  mrg   for (gphi_iterator si = gsi_start_phis (bb); ! gsi_end_p (si);
    300  1.1  mrg        gsi_next (&si))
    301  1.1  mrg     {
    302  1.1  mrg       gphi *phi = si.phi ();
    303  1.1  mrg       use_operand_p use_p;
    304  1.1  mrg       imm_use_iterator iter;
    305  1.1  mrg       FOR_EACH_IMM_USE_FAST (use_p, iter, gimple_phi_result (phi))
    306  1.1  mrg 	{
    307  1.1  mrg 	  gimple *stmt = USE_STMT (use_p);
    308  1.1  mrg 	  if (is_gimple_debug (stmt))
    309  1.1  mrg 	    continue;
    310  1.1  mrg 	  /* If there's a use in the joiner this might be a CSE/DCE
    311  1.1  mrg 	     opportunity, but not if the use is in a conditional
    312  1.1  mrg 	     which makes this a likely if-conversion candidate.  */
    313  1.1  mrg 	  if (gimple_bb (stmt) == bb
    314  1.1  mrg 	      && (!is_gimple_assign (stmt)
    315  1.1  mrg 		  || (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
    316  1.1  mrg 		      != tcc_comparison)))
    317  1.1  mrg 	    {
    318  1.1  mrg 	      found_useful_phi = true;
    319  1.1  mrg 	      break;
    320  1.1  mrg 	    }
    321  1.1  mrg 	  /* If the use is on a loop header PHI and on one path the
    322  1.1  mrg 	     value is unchanged this might expose a jump threading
    323  1.1  mrg 	     opportunity.  */
    324  1.1  mrg 	  if (gimple_code (stmt) == GIMPLE_PHI
    325  1.1  mrg 	      && gimple_bb (stmt) == bb->loop_father->header
    326  1.1  mrg 	      /* But for memory the PHI alone isn't good enough.  */
    327  1.1  mrg 	      && ! virtual_operand_p (gimple_phi_result (stmt)))
    328  1.1  mrg 	    {
    329  1.1  mrg 	      bool found_unchanged_path = false;
    330  1.1  mrg 	      for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
    331  1.1  mrg 		if (gimple_phi_arg_def (phi, i) == gimple_phi_result (stmt))
    332  1.1  mrg 		  {
    333  1.1  mrg 		    found_unchanged_path = true;
    334  1.1  mrg 		    break;
    335  1.1  mrg 		  }
    336  1.1  mrg 	      /* If we found an unchanged path this can only be a threading
    337  1.1  mrg 	         opportunity if we have uses of the loop header PHI result
    338  1.1  mrg 		 in a stmt dominating the merge block.  Otherwise the
    339  1.1  mrg 		 splitting may prevent if-conversion.  */
    340  1.1  mrg 	      if (found_unchanged_path)
    341  1.1  mrg 		{
    342  1.1  mrg 		  use_operand_p use2_p;
    343  1.1  mrg 		  imm_use_iterator iter2;
    344  1.1  mrg 		  FOR_EACH_IMM_USE_FAST (use2_p, iter2, gimple_phi_result (stmt))
    345  1.1  mrg 		    {
    346  1.1  mrg 		      gimple *use_stmt = USE_STMT (use2_p);
    347  1.1  mrg 		      if (is_gimple_debug (use_stmt))
    348  1.1  mrg 			continue;
    349  1.1  mrg 		      basic_block use_bb = gimple_bb (use_stmt);
    350  1.1  mrg 		      if (use_bb != bb
    351  1.1  mrg 			  && dominated_by_p (CDI_DOMINATORS, bb, use_bb))
    352  1.1  mrg 			{
    353  1.1  mrg 			  if (gcond *cond = dyn_cast <gcond *> (use_stmt))
    354  1.1  mrg 			    if (gimple_cond_code (cond) == EQ_EXPR
    355  1.1  mrg 				|| gimple_cond_code (cond) == NE_EXPR)
    356  1.1  mrg 			      found_useful_phi = true;
    357  1.1  mrg 			  break;
    358  1.1  mrg 			}
    359  1.1  mrg 		    }
    360  1.1  mrg 		}
    361  1.1  mrg 	      if (found_useful_phi)
    362  1.1  mrg 		break;
    363  1.1  mrg 	    }
    364  1.1  mrg 	}
    365  1.1  mrg       if (found_useful_phi)
    366  1.1  mrg 	break;
    367  1.1  mrg     }
    368  1.1  mrg   /* There is one exception namely a controlling condition we can propagate
    369  1.1  mrg      an equivalence from to the joiner.  */
    370  1.1  mrg   bool found_cprop_opportunity = false;
    371  1.1  mrg   basic_block dom = get_immediate_dominator (CDI_DOMINATORS, bb);
    372  1.1  mrg   gcond *cond = as_a <gcond *> (last_stmt (dom));
    373  1.1  mrg   if (gimple_cond_code (cond) == EQ_EXPR
    374  1.1  mrg       || gimple_cond_code (cond) == NE_EXPR)
    375  1.1  mrg     for (unsigned i = 0; i < 2; ++i)
    376  1.1  mrg       {
    377  1.1  mrg 	tree op = gimple_op (cond, i);
    378  1.1  mrg 	if (TREE_CODE (op) == SSA_NAME)
    379  1.1  mrg 	  {
    380  1.1  mrg 	    use_operand_p use_p;
    381  1.1  mrg 	    imm_use_iterator iter;
    382  1.1  mrg 	    FOR_EACH_IMM_USE_FAST (use_p, iter, op)
    383  1.1  mrg 	      {
    384  1.1  mrg 		if (is_gimple_debug (USE_STMT (use_p)))
    385  1.1  mrg 		  continue;
    386  1.1  mrg 		if (gimple_bb (USE_STMT (use_p)) == bb)
    387  1.1  mrg 		  {
    388  1.1  mrg 		    found_cprop_opportunity = true;
    389  1.1  mrg 		    break;
    390  1.1  mrg 		  }
    391  1.1  mrg 	      }
    392  1.1  mrg 	  }
    393  1.1  mrg 	if (found_cprop_opportunity)
    394  1.1  mrg 	  break;
    395  1.1  mrg       }
    396  1.1  mrg 
    397  1.1  mrg   if (! found_useful_phi && ! found_cprop_opportunity)
    398  1.1  mrg     {
    399  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
    400  1.1  mrg 	fprintf (dump_file,
    401  1.1  mrg 		 "Block %d is a join that does not expose CSE/DCE/jump-thread "
    402  1.1  mrg 		 "opportunities when duplicated.\n",
    403  1.1  mrg 		 bb->index);
    404  1.1  mrg       return false;
    405  1.1  mrg     }
    406  1.1  mrg 
    407  1.1  mrg   /* We may want something here which looks at dataflow and tries
    408  1.1  mrg      to guess if duplication of BB is likely to result in simplification
    409  1.1  mrg      of instructions in BB in either the original or the duplicate.  */
    410  1.1  mrg 
    411  1.1  mrg   /* Upper Hard limit on the number statements to copy.  */
    412  1.1  mrg   if (num_stmts_in_join
    413  1.1  mrg       >= param_max_jump_thread_duplication_stmts)
    414  1.1  mrg     return false;
    415  1.1  mrg 
    416  1.1  mrg   return true;
    417  1.1  mrg }
    418  1.1  mrg 
    419  1.1  mrg /* If the immediate dominator of the latch of the loop is
    420  1.1  mrg    block with conditional branch, then the loop latch  is
    421  1.1  mrg    duplicated to its predecessors path preserving the SSA
    422  1.1  mrg    semantics.
    423  1.1  mrg 
    424  1.1  mrg    CFG before transformation.
    425  1.1  mrg 
    426  1.1  mrg               2
    427  1.1  mrg               |
    428  1.1  mrg               |
    429  1.1  mrg         +---->3
    430  1.1  mrg         |    / \
    431  1.1  mrg         |   /   \
    432  1.1  mrg         |  4     5
    433  1.1  mrg         |   \   /
    434  1.1  mrg         |    \ /
    435  1.1  mrg         |     6
    436  1.1  mrg         |    / \
    437  1.1  mrg         |   /   \
    438  1.1  mrg         |  8     7
    439  1.1  mrg         |  |     |
    440  1.1  mrg         ---+     E
    441  1.1  mrg 
    442  1.1  mrg 
    443  1.1  mrg 
    444  1.1  mrg     Block 8 is the latch.  We're going to make copies of block 6 (9 & 10)
    445  1.1  mrg     and wire things up so they look like this:
    446  1.1  mrg 
    447  1.1  mrg               2
    448  1.1  mrg               |
    449  1.1  mrg               |
    450  1.1  mrg         +---->3
    451  1.1  mrg         |    / \
    452  1.1  mrg         |   /   \
    453  1.1  mrg         |  4     5
    454  1.1  mrg         |  |     |
    455  1.1  mrg         |  |     |
    456  1.1  mrg         |  9    10
    457  1.1  mrg         |  |\   /|
    458  1.1  mrg         |  | \ / |
    459  1.1  mrg         |  |  7  |
    460  1.1  mrg         |  |  |  |
    461  1.1  mrg         |  |  E  |
    462  1.1  mrg         |  |     |
    463  1.1  mrg         |   \   /
    464  1.1  mrg         |    \ /
    465  1.1  mrg         +-----8
    466  1.1  mrg 
    467  1.1  mrg 
    468  1.1  mrg     Blocks 9 and 10 will get merged into blocks 4 & 5 respectively which
    469  1.1  mrg     enables CSE, DCE and other optimizations to occur on a larger block
    470  1.1  mrg     of code.   */
    471  1.1  mrg 
    472  1.1  mrg static bool
    473  1.1  mrg split_paths ()
    474  1.1  mrg {
    475  1.1  mrg   bool changed = false;
    476  1.1  mrg 
    477  1.1  mrg   loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
    478  1.1  mrg   initialize_original_copy_tables ();
    479  1.1  mrg   calculate_dominance_info (CDI_DOMINATORS);
    480  1.1  mrg 
    481  1.1  mrg   for (auto loop : loops_list (cfun, LI_FROM_INNERMOST))
    482  1.1  mrg     {
    483  1.1  mrg       /* Only split paths if we are optimizing this loop for speed.  */
    484  1.1  mrg       if (!optimize_loop_for_speed_p (loop))
    485  1.1  mrg 	continue;
    486  1.1  mrg 
    487  1.1  mrg       /* See if there is a block that we can duplicate to split the
    488  1.1  mrg 	 path to the loop latch.  */
    489  1.1  mrg       basic_block bb
    490  1.1  mrg 	= find_block_to_duplicate_for_splitting_paths (loop->latch);
    491  1.1  mrg 
    492  1.1  mrg       /* BB is the merge point for an IF-THEN-ELSE we want to transform.
    493  1.1  mrg 
    494  1.1  mrg 	 Essentially we want to create a duplicate of bb and redirect the
    495  1.1  mrg 	 first predecessor of BB to the duplicate (leaving the second
    496  1.1  mrg 	 predecessor as is.  This will split the path leading to the latch
    497  1.1  mrg 	 re-using BB to avoid useless copying.  */
    498  1.1  mrg       if (bb && is_feasible_trace (bb))
    499  1.1  mrg 	{
    500  1.1  mrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
    501  1.1  mrg 	    fprintf (dump_file,
    502  1.1  mrg 		     "Duplicating join block %d into predecessor paths\n",
    503  1.1  mrg 		     bb->index);
    504  1.1  mrg 	  basic_block pred0 = EDGE_PRED (bb, 0)->src;
    505  1.1  mrg 	  if (EDGE_COUNT (pred0->succs) != 1)
    506  1.1  mrg 	    pred0 = EDGE_PRED (bb, 1)->src;
    507  1.1  mrg 	  transform_duplicate (pred0, bb);
    508  1.1  mrg 	  changed = true;
    509  1.1  mrg 
    510  1.1  mrg 	  /* If BB has an outgoing edge marked as IRREDUCIBLE, then
    511  1.1  mrg 	     duplicating BB may result in an irreducible region turning
    512  1.1  mrg 	     into a natural loop.
    513  1.1  mrg 
    514  1.1  mrg 	     Long term we might want to hook this into the block
    515  1.1  mrg 	     duplication code, but as we've seen with similar changes
    516  1.1  mrg 	     for edge removal, that can be somewhat risky.  */
    517  1.1  mrg 	  if (EDGE_SUCC (bb, 0)->flags & EDGE_IRREDUCIBLE_LOOP
    518  1.1  mrg 	      || EDGE_SUCC (bb, 1)->flags & EDGE_IRREDUCIBLE_LOOP)
    519  1.1  mrg 	    {
    520  1.1  mrg 	      if (dump_file && (dump_flags & TDF_DETAILS))
    521  1.1  mrg 		  fprintf (dump_file,
    522  1.1  mrg 			   "Join block %d has EDGE_IRREDUCIBLE_LOOP set.  "
    523  1.1  mrg 			   "Scheduling loop fixups.\n",
    524  1.1  mrg 			   bb->index);
    525  1.1  mrg 	      loops_state_set (LOOPS_NEED_FIXUP);
    526  1.1  mrg 	    }
    527  1.1  mrg 	}
    528  1.1  mrg     }
    529  1.1  mrg 
    530  1.1  mrg   loop_optimizer_finalize ();
    531  1.1  mrg   free_original_copy_tables ();
    532  1.1  mrg   return changed;
    533  1.1  mrg }
    534  1.1  mrg 
    535  1.1  mrg /* Main entry point for splitting paths.  Returns TODO_cleanup_cfg if any
    536  1.1  mrg    paths where split, otherwise return zero.  */
    537  1.1  mrg 
    538  1.1  mrg static unsigned int
    539  1.1  mrg execute_split_paths ()
    540  1.1  mrg {
    541  1.1  mrg   /* If we don't have at least 2 real blocks and backedges in the
    542  1.1  mrg      CFG, then there's no point in trying to perform path splitting.  */
    543  1.1  mrg   if (n_basic_blocks_for_fn (cfun) <= NUM_FIXED_BLOCKS + 1
    544  1.1  mrg       || !mark_dfs_back_edges ())
    545  1.1  mrg     return 0;
    546  1.1  mrg 
    547  1.1  mrg   bool changed = split_paths();
    548  1.1  mrg   if (changed)
    549  1.1  mrg     free_dominance_info (CDI_DOMINATORS);
    550  1.1  mrg 
    551  1.1  mrg   return changed ? TODO_cleanup_cfg : 0;
    552  1.1  mrg }
    553  1.1  mrg 
    554  1.1  mrg static bool
    555  1.1  mrg gate_split_paths ()
    556  1.1  mrg {
    557  1.1  mrg   return flag_split_paths;
    558  1.1  mrg }
    559  1.1  mrg 
    560  1.1  mrg namespace {
    561  1.1  mrg 
    562  1.1  mrg const pass_data pass_data_split_paths =
    563  1.1  mrg {
    564  1.1  mrg   GIMPLE_PASS, /* type */
    565  1.1  mrg   "split-paths", /* name */
    566  1.1  mrg   OPTGROUP_NONE, /* optinfo_flags */
    567  1.1  mrg   TV_SPLIT_PATHS, /* tv_id */
    568  1.1  mrg   PROP_ssa, /* properties_required */
    569  1.1  mrg   0, /* properties_provided */
    570  1.1  mrg   0, /* properties_destroyed */
    571  1.1  mrg   0, /* todo_flags_start */
    572  1.1  mrg   TODO_update_ssa, /* todo_flags_finish */
    573  1.1  mrg };
    574  1.1  mrg 
    575  1.1  mrg class pass_split_paths : public gimple_opt_pass
    576  1.1  mrg {
    577  1.1  mrg    public:
    578  1.1  mrg     pass_split_paths (gcc::context *ctxt)
    579  1.1  mrg       : gimple_opt_pass (pass_data_split_paths, ctxt)
    580  1.1  mrg     {}
    581  1.1  mrg    /* opt_pass methods: */
    582  1.1  mrg    opt_pass * clone () { return new pass_split_paths (m_ctxt); }
    583  1.1  mrg    virtual bool gate (function *) { return gate_split_paths (); }
    584  1.1  mrg    virtual unsigned int execute (function *) { return execute_split_paths (); }
    585  1.1  mrg 
    586  1.1  mrg }; // class pass_split_paths
    587  1.1  mrg 
    588  1.1  mrg } // anon namespace
    589  1.1  mrg 
    590  1.1  mrg gimple_opt_pass *
    591  1.1  mrg make_pass_split_paths (gcc::context *ctxt)
    592  1.1  mrg {
    593  1.1  mrg   return new pass_split_paths (ctxt);
    594  1.1  mrg }
    595