Home | History | Annotate | Line # | Download | only in gcc
tree-ssa-sink.cc revision 1.1
      1  1.1  mrg /* Code sinking for trees
      2  1.1  mrg    Copyright (C) 2001-2022 Free Software Foundation, Inc.
      3  1.1  mrg    Contributed by Daniel Berlin <dan (at) dberlin.org>
      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 "cfghooks.h"
     28  1.1  mrg #include "tree-pass.h"
     29  1.1  mrg #include "ssa.h"
     30  1.1  mrg #include "gimple-pretty-print.h"
     31  1.1  mrg #include "fold-const.h"
     32  1.1  mrg #include "stor-layout.h"
     33  1.1  mrg #include "cfganal.h"
     34  1.1  mrg #include "gimple-iterator.h"
     35  1.1  mrg #include "tree-cfg.h"
     36  1.1  mrg #include "cfgloop.h"
     37  1.1  mrg #include "tree-eh.h"
     38  1.1  mrg #include "tree-dfa.h"
     39  1.1  mrg 
     40  1.1  mrg /* TODO:
     41  1.1  mrg    1. Sinking store only using scalar promotion (IE without moving the RHS):
     42  1.1  mrg 
     43  1.1  mrg    *q = p;
     44  1.1  mrg    p = p + 1;
     45  1.1  mrg    if (something)
     46  1.1  mrg      *q = <not p>;
     47  1.1  mrg    else
     48  1.1  mrg      y = *q;
     49  1.1  mrg 
     50  1.1  mrg 
     51  1.1  mrg    should become
     52  1.1  mrg    sinktemp = p;
     53  1.1  mrg    p = p + 1;
     54  1.1  mrg    if (something)
     55  1.1  mrg      *q = <not p>;
     56  1.1  mrg    else
     57  1.1  mrg    {
     58  1.1  mrg      *q = sinktemp;
     59  1.1  mrg      y = *q
     60  1.1  mrg    }
     61  1.1  mrg    Store copy propagation will take care of the store elimination above.
     62  1.1  mrg 
     63  1.1  mrg 
     64  1.1  mrg    2. Sinking using Partial Dead Code Elimination.  */
     65  1.1  mrg 
     66  1.1  mrg 
     67  1.1  mrg static struct
     68  1.1  mrg {
     69  1.1  mrg   /* The number of statements sunk down the flowgraph by code sinking.  */
     70  1.1  mrg   int sunk;
     71  1.1  mrg 
     72  1.1  mrg   /* The number of stores commoned and sunk down by store commoning.  */
     73  1.1  mrg   int commoned;
     74  1.1  mrg } sink_stats;
     75  1.1  mrg 
     76  1.1  mrg 
     77  1.1  mrg /* Given a PHI, and one of its arguments (DEF), find the edge for
     78  1.1  mrg    that argument and return it.  If the argument occurs twice in the PHI node,
     79  1.1  mrg    we return NULL.  */
     80  1.1  mrg 
     81  1.1  mrg static basic_block
     82  1.1  mrg find_bb_for_arg (gphi *phi, tree def)
     83  1.1  mrg {
     84  1.1  mrg   size_t i;
     85  1.1  mrg   bool foundone = false;
     86  1.1  mrg   basic_block result = NULL;
     87  1.1  mrg   for (i = 0; i < gimple_phi_num_args (phi); i++)
     88  1.1  mrg     if (PHI_ARG_DEF (phi, i) == def)
     89  1.1  mrg       {
     90  1.1  mrg 	if (foundone)
     91  1.1  mrg 	  return NULL;
     92  1.1  mrg 	foundone = true;
     93  1.1  mrg 	result = gimple_phi_arg_edge (phi, i)->src;
     94  1.1  mrg       }
     95  1.1  mrg   return result;
     96  1.1  mrg }
     97  1.1  mrg 
     98  1.1  mrg /* When the first immediate use is in a statement, then return true if all
     99  1.1  mrg    immediate uses in IMM are in the same statement.
    100  1.1  mrg    We could also do the case where  the first immediate use is in a phi node,
    101  1.1  mrg    and all the other uses are in phis in the same basic block, but this
    102  1.1  mrg    requires some expensive checking later (you have to make sure no def/vdef
    103  1.1  mrg    in the statement occurs for multiple edges in the various phi nodes it's
    104  1.1  mrg    used in, so that you only have one place you can sink it to.  */
    105  1.1  mrg 
    106  1.1  mrg static bool
    107  1.1  mrg all_immediate_uses_same_place (def_operand_p def_p)
    108  1.1  mrg {
    109  1.1  mrg   tree var = DEF_FROM_PTR (def_p);
    110  1.1  mrg   imm_use_iterator imm_iter;
    111  1.1  mrg   use_operand_p use_p;
    112  1.1  mrg 
    113  1.1  mrg   gimple *firstuse = NULL;
    114  1.1  mrg   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var)
    115  1.1  mrg     {
    116  1.1  mrg       if (is_gimple_debug (USE_STMT (use_p)))
    117  1.1  mrg 	continue;
    118  1.1  mrg       if (firstuse == NULL)
    119  1.1  mrg 	firstuse = USE_STMT (use_p);
    120  1.1  mrg       else
    121  1.1  mrg 	if (firstuse != USE_STMT (use_p))
    122  1.1  mrg 	  return false;
    123  1.1  mrg     }
    124  1.1  mrg 
    125  1.1  mrg   return true;
    126  1.1  mrg }
    127  1.1  mrg 
    128  1.1  mrg /* Find the nearest common dominator of all of the immediate uses in IMM.  */
    129  1.1  mrg 
    130  1.1  mrg static basic_block
    131  1.1  mrg nearest_common_dominator_of_uses (def_operand_p def_p, bool *debug_stmts)
    132  1.1  mrg {
    133  1.1  mrg   tree var = DEF_FROM_PTR (def_p);
    134  1.1  mrg   auto_bitmap blocks;
    135  1.1  mrg   basic_block commondom;
    136  1.1  mrg   unsigned int j;
    137  1.1  mrg   bitmap_iterator bi;
    138  1.1  mrg   imm_use_iterator imm_iter;
    139  1.1  mrg   use_operand_p use_p;
    140  1.1  mrg 
    141  1.1  mrg   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var)
    142  1.1  mrg     {
    143  1.1  mrg       gimple *usestmt = USE_STMT (use_p);
    144  1.1  mrg       basic_block useblock;
    145  1.1  mrg 
    146  1.1  mrg       if (gphi *phi = dyn_cast <gphi *> (usestmt))
    147  1.1  mrg 	{
    148  1.1  mrg 	  int idx = PHI_ARG_INDEX_FROM_USE (use_p);
    149  1.1  mrg 
    150  1.1  mrg 	  useblock = gimple_phi_arg_edge (phi, idx)->src;
    151  1.1  mrg 	}
    152  1.1  mrg       else if (is_gimple_debug (usestmt))
    153  1.1  mrg 	{
    154  1.1  mrg 	  *debug_stmts = true;
    155  1.1  mrg 	  continue;
    156  1.1  mrg 	}
    157  1.1  mrg       else
    158  1.1  mrg 	{
    159  1.1  mrg 	  useblock = gimple_bb (usestmt);
    160  1.1  mrg 	}
    161  1.1  mrg 
    162  1.1  mrg       /* Short circuit. Nothing dominates the entry block.  */
    163  1.1  mrg       if (useblock == ENTRY_BLOCK_PTR_FOR_FN (cfun))
    164  1.1  mrg 	return NULL;
    165  1.1  mrg 
    166  1.1  mrg       bitmap_set_bit (blocks, useblock->index);
    167  1.1  mrg     }
    168  1.1  mrg   commondom = BASIC_BLOCK_FOR_FN (cfun, bitmap_first_set_bit (blocks));
    169  1.1  mrg   EXECUTE_IF_SET_IN_BITMAP (blocks, 0, j, bi)
    170  1.1  mrg     commondom = nearest_common_dominator (CDI_DOMINATORS, commondom,
    171  1.1  mrg 					  BASIC_BLOCK_FOR_FN (cfun, j));
    172  1.1  mrg   return commondom;
    173  1.1  mrg }
    174  1.1  mrg 
    175  1.1  mrg /* Given EARLY_BB and LATE_BB, two blocks in a path through the dominator
    176  1.1  mrg    tree, return the best basic block between them (inclusive) to place
    177  1.1  mrg    statements.
    178  1.1  mrg 
    179  1.1  mrg    We want the most control dependent block in the shallowest loop nest.
    180  1.1  mrg 
    181  1.1  mrg    If the resulting block is in a shallower loop nest, then use it.  Else
    182  1.1  mrg    only use the resulting block if it has significantly lower execution
    183  1.1  mrg    frequency than EARLY_BB to avoid gratuitous statement movement.  We
    184  1.1  mrg    consider statements with VOPS more desirable to move.
    185  1.1  mrg 
    186  1.1  mrg    This pass would obviously benefit from PDO as it utilizes block
    187  1.1  mrg    frequencies.  It would also benefit from recomputing frequencies
    188  1.1  mrg    if profile data is not available since frequencies often get out
    189  1.1  mrg    of sync with reality.  */
    190  1.1  mrg 
    191  1.1  mrg static basic_block
    192  1.1  mrg select_best_block (basic_block early_bb,
    193  1.1  mrg 		   basic_block late_bb,
    194  1.1  mrg 		   gimple *stmt)
    195  1.1  mrg {
    196  1.1  mrg   basic_block best_bb = late_bb;
    197  1.1  mrg   basic_block temp_bb = late_bb;
    198  1.1  mrg   int threshold;
    199  1.1  mrg 
    200  1.1  mrg   while (temp_bb != early_bb)
    201  1.1  mrg     {
    202  1.1  mrg       /* If we've moved into a lower loop nest, then that becomes
    203  1.1  mrg 	 our best block.  */
    204  1.1  mrg       if (bb_loop_depth (temp_bb) < bb_loop_depth (best_bb))
    205  1.1  mrg 	best_bb = temp_bb;
    206  1.1  mrg 
    207  1.1  mrg       /* Walk up the dominator tree, hopefully we'll find a shallower
    208  1.1  mrg  	 loop nest.  */
    209  1.1  mrg       temp_bb = get_immediate_dominator (CDI_DOMINATORS, temp_bb);
    210  1.1  mrg     }
    211  1.1  mrg 
    212  1.1  mrg   /* If we found a shallower loop nest, then we always consider that
    213  1.1  mrg      a win.  This will always give us the most control dependent block
    214  1.1  mrg      within that loop nest.  */
    215  1.1  mrg   if (bb_loop_depth (best_bb) < bb_loop_depth (early_bb))
    216  1.1  mrg     return best_bb;
    217  1.1  mrg 
    218  1.1  mrg   /* Get the sinking threshold.  If the statement to be moved has memory
    219  1.1  mrg      operands, then increase the threshold by 7% as those are even more
    220  1.1  mrg      profitable to avoid, clamping at 100%.  */
    221  1.1  mrg   threshold = param_sink_frequency_threshold;
    222  1.1  mrg   if (gimple_vuse (stmt) || gimple_vdef (stmt))
    223  1.1  mrg     {
    224  1.1  mrg       threshold += 7;
    225  1.1  mrg       if (threshold > 100)
    226  1.1  mrg 	threshold = 100;
    227  1.1  mrg     }
    228  1.1  mrg 
    229  1.1  mrg   /* If BEST_BB is at the same nesting level, then require it to have
    230  1.1  mrg      significantly lower execution frequency to avoid gratuitous movement.  */
    231  1.1  mrg   if (bb_loop_depth (best_bb) == bb_loop_depth (early_bb)
    232  1.1  mrg       /* If result of comparsion is unknown, prefer EARLY_BB.
    233  1.1  mrg 	 Thus use !(...>=..) rather than (...<...)  */
    234  1.1  mrg       && !(best_bb->count.apply_scale (100, 1)
    235  1.1  mrg 	   >= early_bb->count.apply_scale (threshold, 1)))
    236  1.1  mrg     return best_bb;
    237  1.1  mrg 
    238  1.1  mrg   /* No better block found, so return EARLY_BB, which happens to be the
    239  1.1  mrg      statement's original block.  */
    240  1.1  mrg   return early_bb;
    241  1.1  mrg }
    242  1.1  mrg 
    243  1.1  mrg /* Given a statement (STMT) and the basic block it is currently in (FROMBB),
    244  1.1  mrg    determine the location to sink the statement to, if any.
    245  1.1  mrg    Returns true if there is such location; in that case, TOGSI points to the
    246  1.1  mrg    statement before that STMT should be moved.  */
    247  1.1  mrg 
    248  1.1  mrg static bool
    249  1.1  mrg statement_sink_location (gimple *stmt, basic_block frombb,
    250  1.1  mrg 			 gimple_stmt_iterator *togsi, bool *zero_uses_p)
    251  1.1  mrg {
    252  1.1  mrg   gimple *use;
    253  1.1  mrg   use_operand_p one_use = NULL_USE_OPERAND_P;
    254  1.1  mrg   basic_block sinkbb;
    255  1.1  mrg   use_operand_p use_p;
    256  1.1  mrg   def_operand_p def_p;
    257  1.1  mrg   ssa_op_iter iter;
    258  1.1  mrg   imm_use_iterator imm_iter;
    259  1.1  mrg 
    260  1.1  mrg   *zero_uses_p = false;
    261  1.1  mrg 
    262  1.1  mrg   /* We only can sink assignments and non-looping const/pure calls.  */
    263  1.1  mrg   int cf;
    264  1.1  mrg   if (!is_gimple_assign (stmt)
    265  1.1  mrg       && (!is_gimple_call (stmt)
    266  1.1  mrg 	  || !((cf = gimple_call_flags (stmt)) & (ECF_CONST|ECF_PURE))
    267  1.1  mrg 	  || (cf & ECF_LOOPING_CONST_OR_PURE)))
    268  1.1  mrg     return false;
    269  1.1  mrg 
    270  1.1  mrg   /* We only can sink stmts with a single definition.  */
    271  1.1  mrg   def_p = single_ssa_def_operand (stmt, SSA_OP_ALL_DEFS);
    272  1.1  mrg   if (def_p == NULL_DEF_OPERAND_P)
    273  1.1  mrg     return false;
    274  1.1  mrg 
    275  1.1  mrg   /* There are a few classes of things we can't or don't move, some because we
    276  1.1  mrg      don't have code to handle it, some because it's not profitable and some
    277  1.1  mrg      because it's not legal.
    278  1.1  mrg 
    279  1.1  mrg      We can't sink things that may be global stores, at least not without
    280  1.1  mrg      calculating a lot more information, because we may cause it to no longer
    281  1.1  mrg      be seen by an external routine that needs it depending on where it gets
    282  1.1  mrg      moved to.
    283  1.1  mrg 
    284  1.1  mrg      We can't sink statements that end basic blocks without splitting the
    285  1.1  mrg      incoming edge for the sink location to place it there.
    286  1.1  mrg 
    287  1.1  mrg      We can't sink statements that have volatile operands.
    288  1.1  mrg 
    289  1.1  mrg      We don't want to sink dead code, so anything with 0 immediate uses is not
    290  1.1  mrg      sunk.
    291  1.1  mrg 
    292  1.1  mrg      Don't sink BLKmode assignments if current function has any local explicit
    293  1.1  mrg      register variables, as BLKmode assignments may involve memcpy or memset
    294  1.1  mrg      calls or, on some targets, inline expansion thereof that sometimes need
    295  1.1  mrg      to use specific hard registers.
    296  1.1  mrg 
    297  1.1  mrg   */
    298  1.1  mrg   if (stmt_ends_bb_p (stmt)
    299  1.1  mrg       || gimple_has_side_effects (stmt)
    300  1.1  mrg       || (cfun->has_local_explicit_reg_vars
    301  1.1  mrg 	  && TYPE_MODE (TREE_TYPE (gimple_get_lhs (stmt))) == BLKmode))
    302  1.1  mrg     return false;
    303  1.1  mrg 
    304  1.1  mrg   /* Return if there are no immediate uses of this stmt.  */
    305  1.1  mrg   if (has_zero_uses (DEF_FROM_PTR (def_p)))
    306  1.1  mrg     {
    307  1.1  mrg       *zero_uses_p = true;
    308  1.1  mrg       return false;
    309  1.1  mrg     }
    310  1.1  mrg 
    311  1.1  mrg   if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (DEF_FROM_PTR (def_p)))
    312  1.1  mrg     return false;
    313  1.1  mrg 
    314  1.1  mrg   FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
    315  1.1  mrg     {
    316  1.1  mrg       tree use = USE_FROM_PTR (use_p);
    317  1.1  mrg       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (use))
    318  1.1  mrg 	return false;
    319  1.1  mrg     }
    320  1.1  mrg 
    321  1.1  mrg   use = NULL;
    322  1.1  mrg 
    323  1.1  mrg   /* If stmt is a store the one and only use needs to be the VOP
    324  1.1  mrg      merging PHI node.  */
    325  1.1  mrg   if (virtual_operand_p (DEF_FROM_PTR (def_p)))
    326  1.1  mrg     {
    327  1.1  mrg       FOR_EACH_IMM_USE_FAST (use_p, imm_iter, DEF_FROM_PTR (def_p))
    328  1.1  mrg 	{
    329  1.1  mrg 	  gimple *use_stmt = USE_STMT (use_p);
    330  1.1  mrg 
    331  1.1  mrg 	  /* A killing definition is not a use.  */
    332  1.1  mrg 	  if ((gimple_has_lhs (use_stmt)
    333  1.1  mrg 	       && operand_equal_p (gimple_get_lhs (stmt),
    334  1.1  mrg 				   gimple_get_lhs (use_stmt), 0))
    335  1.1  mrg 	      || stmt_kills_ref_p (use_stmt, gimple_get_lhs (stmt)))
    336  1.1  mrg 	    {
    337  1.1  mrg 	      /* If use_stmt is or might be a nop assignment then USE_STMT
    338  1.1  mrg 	         acts as a use as well as definition.  */
    339  1.1  mrg 	      if (stmt != use_stmt
    340  1.1  mrg 		  && ref_maybe_used_by_stmt_p (use_stmt,
    341  1.1  mrg 					       gimple_get_lhs (stmt)))
    342  1.1  mrg 		return false;
    343  1.1  mrg 	      continue;
    344  1.1  mrg 	    }
    345  1.1  mrg 
    346  1.1  mrg 	  if (gimple_code (use_stmt) != GIMPLE_PHI)
    347  1.1  mrg 	    return false;
    348  1.1  mrg 
    349  1.1  mrg 	  if (use
    350  1.1  mrg 	      && use != use_stmt)
    351  1.1  mrg 	    return false;
    352  1.1  mrg 
    353  1.1  mrg 	  use = use_stmt;
    354  1.1  mrg 	}
    355  1.1  mrg       if (!use)
    356  1.1  mrg 	return false;
    357  1.1  mrg     }
    358  1.1  mrg   /* If all the immediate uses are not in the same place, find the nearest
    359  1.1  mrg      common dominator of all the immediate uses.  For PHI nodes, we have to
    360  1.1  mrg      find the nearest common dominator of all of the predecessor blocks, since
    361  1.1  mrg      that is where insertion would have to take place.  */
    362  1.1  mrg   else if (gimple_vuse (stmt)
    363  1.1  mrg 	   || !all_immediate_uses_same_place (def_p))
    364  1.1  mrg     {
    365  1.1  mrg       bool debug_stmts = false;
    366  1.1  mrg       basic_block commondom = nearest_common_dominator_of_uses (def_p,
    367  1.1  mrg 								&debug_stmts);
    368  1.1  mrg 
    369  1.1  mrg       if (commondom == frombb)
    370  1.1  mrg 	return false;
    371  1.1  mrg 
    372  1.1  mrg       /* If this is a load then do not sink past any stores.
    373  1.1  mrg 	 Look for virtual definitions in the path from frombb to the sink
    374  1.1  mrg 	 location computed from the real uses and if found, adjust
    375  1.1  mrg 	 that it a common dominator.  */
    376  1.1  mrg       if (gimple_vuse (stmt))
    377  1.1  mrg 	{
    378  1.1  mrg 	  /* Do not sink loads from hard registers.  */
    379  1.1  mrg 	  if (gimple_assign_single_p (stmt)
    380  1.1  mrg 	      && TREE_CODE (gimple_assign_rhs1 (stmt)) == VAR_DECL
    381  1.1  mrg 	      && DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt)))
    382  1.1  mrg 	    return false;
    383  1.1  mrg 
    384  1.1  mrg 	  imm_use_iterator imm_iter;
    385  1.1  mrg 	  use_operand_p use_p;
    386  1.1  mrg 	  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, gimple_vuse (stmt))
    387  1.1  mrg 	    {
    388  1.1  mrg 	      gimple *use_stmt = USE_STMT (use_p);
    389  1.1  mrg 	      basic_block bb = gimple_bb (use_stmt);
    390  1.1  mrg 	      /* For PHI nodes the block we know sth about is the incoming block
    391  1.1  mrg 		 with the use.  */
    392  1.1  mrg 	      if (gimple_code (use_stmt) == GIMPLE_PHI)
    393  1.1  mrg 		{
    394  1.1  mrg 		  /* If the PHI defines the virtual operand, ignore it.  */
    395  1.1  mrg 		  if (gimple_phi_result (use_stmt) == gimple_vuse (stmt))
    396  1.1  mrg 		    continue;
    397  1.1  mrg 		  /* In case the PHI node post-dominates the current insert
    398  1.1  mrg 		     location we can disregard it.  But make sure it is not
    399  1.1  mrg 		     dominating it as well as can happen in a CFG cycle.  */
    400  1.1  mrg 		  if (commondom != bb
    401  1.1  mrg 		      && !dominated_by_p (CDI_DOMINATORS, commondom, bb)
    402  1.1  mrg 		      && dominated_by_p (CDI_POST_DOMINATORS, commondom, bb)
    403  1.1  mrg 		      /* If the blocks are possibly within the same irreducible
    404  1.1  mrg 			 cycle the above check breaks down.  */
    405  1.1  mrg 		      && !((bb->flags & commondom->flags & BB_IRREDUCIBLE_LOOP)
    406  1.1  mrg 			   && bb->loop_father == commondom->loop_father)
    407  1.1  mrg 		      && !((commondom->flags & BB_IRREDUCIBLE_LOOP)
    408  1.1  mrg 			   && flow_loop_nested_p (commondom->loop_father,
    409  1.1  mrg 						  bb->loop_father))
    410  1.1  mrg 		      && !((bb->flags & BB_IRREDUCIBLE_LOOP)
    411  1.1  mrg 			   && flow_loop_nested_p (bb->loop_father,
    412  1.1  mrg 						  commondom->loop_father)))
    413  1.1  mrg 		    continue;
    414  1.1  mrg 		  bb = EDGE_PRED (bb, PHI_ARG_INDEX_FROM_USE (use_p))->src;
    415  1.1  mrg 		}
    416  1.1  mrg 	      else if (!gimple_vdef (use_stmt))
    417  1.1  mrg 		continue;
    418  1.1  mrg 	      /* If the use is not dominated by the path entry it is not on
    419  1.1  mrg 		 the path.  */
    420  1.1  mrg 	      if (!dominated_by_p (CDI_DOMINATORS, bb, frombb))
    421  1.1  mrg 		continue;
    422  1.1  mrg 	      /* There is no easy way to disregard defs not on the path from
    423  1.1  mrg 		 frombb to commondom so just consider them all.  */
    424  1.1  mrg 	      commondom = nearest_common_dominator (CDI_DOMINATORS,
    425  1.1  mrg 						    bb, commondom);
    426  1.1  mrg 	      if (commondom == frombb)
    427  1.1  mrg 		return false;
    428  1.1  mrg 	    }
    429  1.1  mrg 	}
    430  1.1  mrg 
    431  1.1  mrg       /* Our common dominator has to be dominated by frombb in order to be a
    432  1.1  mrg 	 trivially safe place to put this statement, since it has multiple
    433  1.1  mrg 	 uses.  */
    434  1.1  mrg       if (!dominated_by_p (CDI_DOMINATORS, commondom, frombb))
    435  1.1  mrg 	return false;
    436  1.1  mrg 
    437  1.1  mrg       commondom = select_best_block (frombb, commondom, stmt);
    438  1.1  mrg 
    439  1.1  mrg       if (commondom == frombb)
    440  1.1  mrg 	return false;
    441  1.1  mrg 
    442  1.1  mrg       *togsi = gsi_after_labels (commondom);
    443  1.1  mrg 
    444  1.1  mrg       return true;
    445  1.1  mrg     }
    446  1.1  mrg   else
    447  1.1  mrg     {
    448  1.1  mrg       FOR_EACH_IMM_USE_FAST (one_use, imm_iter, DEF_FROM_PTR (def_p))
    449  1.1  mrg 	{
    450  1.1  mrg 	  if (is_gimple_debug (USE_STMT (one_use)))
    451  1.1  mrg 	    continue;
    452  1.1  mrg 	  break;
    453  1.1  mrg 	}
    454  1.1  mrg       use = USE_STMT (one_use);
    455  1.1  mrg 
    456  1.1  mrg       if (gimple_code (use) != GIMPLE_PHI)
    457  1.1  mrg 	{
    458  1.1  mrg 	  sinkbb = select_best_block (frombb, gimple_bb (use), stmt);
    459  1.1  mrg 
    460  1.1  mrg 	  if (sinkbb == frombb)
    461  1.1  mrg 	    return false;
    462  1.1  mrg 
    463  1.1  mrg 	  if (sinkbb == gimple_bb (use))
    464  1.1  mrg 	    *togsi = gsi_for_stmt (use);
    465  1.1  mrg 	  else
    466  1.1  mrg 	    *togsi = gsi_after_labels (sinkbb);
    467  1.1  mrg 
    468  1.1  mrg 	  return true;
    469  1.1  mrg 	}
    470  1.1  mrg     }
    471  1.1  mrg 
    472  1.1  mrg   sinkbb = find_bb_for_arg (as_a <gphi *> (use), DEF_FROM_PTR (def_p));
    473  1.1  mrg 
    474  1.1  mrg   /* This can happen if there are multiple uses in a PHI.  */
    475  1.1  mrg   if (!sinkbb)
    476  1.1  mrg     return false;
    477  1.1  mrg 
    478  1.1  mrg   sinkbb = select_best_block (frombb, sinkbb, stmt);
    479  1.1  mrg   if (!sinkbb || sinkbb == frombb)
    480  1.1  mrg     return false;
    481  1.1  mrg 
    482  1.1  mrg   /* If the latch block is empty, don't make it non-empty by sinking
    483  1.1  mrg      something into it.  */
    484  1.1  mrg   if (sinkbb == frombb->loop_father->latch
    485  1.1  mrg       && empty_block_p (sinkbb))
    486  1.1  mrg     return false;
    487  1.1  mrg 
    488  1.1  mrg   *togsi = gsi_after_labels (sinkbb);
    489  1.1  mrg 
    490  1.1  mrg   return true;
    491  1.1  mrg }
    492  1.1  mrg 
    493  1.1  mrg /* Very simplistic code to sink common stores from the predecessor through
    494  1.1  mrg    our virtual PHI.  We do this before sinking stmts from BB as it might
    495  1.1  mrg    expose sinking opportunities of the merged stores.
    496  1.1  mrg    Once we have partial dead code elimination through sth like SSU-PRE this
    497  1.1  mrg    should be moved there.  */
    498  1.1  mrg 
    499  1.1  mrg static unsigned
    500  1.1  mrg sink_common_stores_to_bb (basic_block bb)
    501  1.1  mrg {
    502  1.1  mrg   unsigned todo = 0;
    503  1.1  mrg   gphi *phi;
    504  1.1  mrg 
    505  1.1  mrg   if (EDGE_COUNT (bb->preds) > 1
    506  1.1  mrg       && (phi = get_virtual_phi (bb)))
    507  1.1  mrg     {
    508  1.1  mrg       /* Repeat until no more common stores are found.  */
    509  1.1  mrg       while (1)
    510  1.1  mrg 	{
    511  1.1  mrg 	  gimple *first_store = NULL;
    512  1.1  mrg 	  auto_vec <tree, 5> vdefs;
    513  1.1  mrg 	  gimple_stmt_iterator gsi;
    514  1.1  mrg 
    515  1.1  mrg 	  /* Search for common stores defined by all virtual PHI args.
    516  1.1  mrg 	     ???  Common stores not present in all predecessors could
    517  1.1  mrg 	     be handled by inserting a forwarder to sink to.  Generally
    518  1.1  mrg 	     this involves deciding which stores to do this for if
    519  1.1  mrg 	     multiple common stores are present for different sets of
    520  1.1  mrg 	     predecessors.  See PR11832 for an interesting case.  */
    521  1.1  mrg 	  for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
    522  1.1  mrg 	    {
    523  1.1  mrg 	      tree arg = gimple_phi_arg_def (phi, i);
    524  1.1  mrg 	      gimple *def = SSA_NAME_DEF_STMT (arg);
    525  1.1  mrg 	      if (! is_gimple_assign (def)
    526  1.1  mrg 		  || stmt_can_throw_internal (cfun, def)
    527  1.1  mrg 		  || (gimple_phi_arg_edge (phi, i)->flags & EDGE_ABNORMAL)
    528  1.1  mrg 		  || stmt_references_abnormal_ssa_name (def))
    529  1.1  mrg 		{
    530  1.1  mrg 		  /* ???  We could handle some cascading with the def being
    531  1.1  mrg 		     another PHI.  We'd have to insert multiple PHIs for
    532  1.1  mrg 		     the rhs then though (if they are not all equal).  */
    533  1.1  mrg 		  first_store = NULL;
    534  1.1  mrg 		  break;
    535  1.1  mrg 		}
    536  1.1  mrg 	      /* ???  Do not try to do anything fancy with aliasing, thus
    537  1.1  mrg 		 do not sink across non-aliased loads (or even stores,
    538  1.1  mrg 		 so different store order will make the sinking fail).  */
    539  1.1  mrg 	      bool all_uses_on_phi = true;
    540  1.1  mrg 	      imm_use_iterator iter;
    541  1.1  mrg 	      use_operand_p use_p;
    542  1.1  mrg 	      FOR_EACH_IMM_USE_FAST (use_p, iter, arg)
    543  1.1  mrg 		if (USE_STMT (use_p) != phi)
    544  1.1  mrg 		  {
    545  1.1  mrg 		    all_uses_on_phi = false;
    546  1.1  mrg 		    break;
    547  1.1  mrg 		  }
    548  1.1  mrg 	      if (! all_uses_on_phi)
    549  1.1  mrg 		{
    550  1.1  mrg 		  first_store = NULL;
    551  1.1  mrg 		  break;
    552  1.1  mrg 		}
    553  1.1  mrg 	      /* Check all stores are to the same LHS.  */
    554  1.1  mrg 	      if (! first_store)
    555  1.1  mrg 		first_store = def;
    556  1.1  mrg 	      /* ??? We could handle differing SSA uses in the LHS by inserting
    557  1.1  mrg 		 PHIs for them.  */
    558  1.1  mrg 	      else if (! operand_equal_p (gimple_assign_lhs (first_store),
    559  1.1  mrg 					  gimple_assign_lhs (def), 0)
    560  1.1  mrg 		       || (gimple_clobber_p (first_store)
    561  1.1  mrg 			   != gimple_clobber_p (def)))
    562  1.1  mrg 		{
    563  1.1  mrg 		  first_store = NULL;
    564  1.1  mrg 		  break;
    565  1.1  mrg 		}
    566  1.1  mrg 	      vdefs.safe_push (arg);
    567  1.1  mrg 	    }
    568  1.1  mrg 	  if (! first_store)
    569  1.1  mrg 	    break;
    570  1.1  mrg 
    571  1.1  mrg 	  /* Check if we need a PHI node to merge the stored values.  */
    572  1.1  mrg 	  bool allsame = true;
    573  1.1  mrg 	  if (!gimple_clobber_p (first_store))
    574  1.1  mrg 	    for (unsigned i = 1; i < vdefs.length (); ++i)
    575  1.1  mrg 	      {
    576  1.1  mrg 		gimple *def = SSA_NAME_DEF_STMT (vdefs[i]);
    577  1.1  mrg 		if (! operand_equal_p (gimple_assign_rhs1 (first_store),
    578  1.1  mrg 				       gimple_assign_rhs1 (def), 0))
    579  1.1  mrg 		  {
    580  1.1  mrg 		    allsame = false;
    581  1.1  mrg 		    break;
    582  1.1  mrg 		  }
    583  1.1  mrg 	      }
    584  1.1  mrg 
    585  1.1  mrg 	  /* We cannot handle aggregate values if we need to merge them.  */
    586  1.1  mrg 	  tree type = TREE_TYPE (gimple_assign_lhs (first_store));
    587  1.1  mrg 	  if (! allsame
    588  1.1  mrg 	      && ! is_gimple_reg_type (type))
    589  1.1  mrg 	    break;
    590  1.1  mrg 
    591  1.1  mrg 	  if (dump_enabled_p ())
    592  1.1  mrg 	    {
    593  1.1  mrg 	      dump_printf_loc (MSG_OPTIMIZED_LOCATIONS,
    594  1.1  mrg 			       first_store,
    595  1.1  mrg 			       "sinking common stores %sto ",
    596  1.1  mrg 			       allsame ? "with same value " : "");
    597  1.1  mrg 	      dump_generic_expr (MSG_OPTIMIZED_LOCATIONS, TDF_SLIM,
    598  1.1  mrg 				 gimple_assign_lhs (first_store));
    599  1.1  mrg 	      dump_printf (MSG_OPTIMIZED_LOCATIONS, "\n");
    600  1.1  mrg 	    }
    601  1.1  mrg 
    602  1.1  mrg 	  /* Insert a PHI to merge differing stored values if necessary.
    603  1.1  mrg 	     Note that in general inserting PHIs isn't a very good idea as
    604  1.1  mrg 	     it makes the job of coalescing and register allocation harder.
    605  1.1  mrg 	     Even common SSA uses on the rhs/lhs might extend their lifetime
    606  1.1  mrg 	     across multiple edges by this code motion which makes
    607  1.1  mrg 	     register allocation harder.  */
    608  1.1  mrg 	  tree from;
    609  1.1  mrg 	  if (! allsame)
    610  1.1  mrg 	    {
    611  1.1  mrg 	      from = make_ssa_name (type);
    612  1.1  mrg 	      gphi *newphi = create_phi_node (from, bb);
    613  1.1  mrg 	      for (unsigned i = 0; i < vdefs.length (); ++i)
    614  1.1  mrg 		{
    615  1.1  mrg 		  gimple *def = SSA_NAME_DEF_STMT (vdefs[i]);
    616  1.1  mrg 		  add_phi_arg (newphi, gimple_assign_rhs1 (def),
    617  1.1  mrg 			       EDGE_PRED (bb, i), UNKNOWN_LOCATION);
    618  1.1  mrg 		}
    619  1.1  mrg 	    }
    620  1.1  mrg 	  else
    621  1.1  mrg 	    from = gimple_assign_rhs1 (first_store);
    622  1.1  mrg 
    623  1.1  mrg 	  /* Remove all stores.  */
    624  1.1  mrg 	  for (unsigned i = 0; i < vdefs.length (); ++i)
    625  1.1  mrg 	    TREE_VISITED (vdefs[i]) = 1;
    626  1.1  mrg 	  for (unsigned i = 0; i < vdefs.length (); ++i)
    627  1.1  mrg 	    /* If we have more than one use of a VDEF on the PHI make sure
    628  1.1  mrg 	       we remove the defining stmt only once.  */
    629  1.1  mrg 	    if (TREE_VISITED (vdefs[i]))
    630  1.1  mrg 	      {
    631  1.1  mrg 		TREE_VISITED (vdefs[i]) = 0;
    632  1.1  mrg 		gimple *def = SSA_NAME_DEF_STMT (vdefs[i]);
    633  1.1  mrg 		gsi = gsi_for_stmt (def);
    634  1.1  mrg 		unlink_stmt_vdef (def);
    635  1.1  mrg 		gsi_remove (&gsi, true);
    636  1.1  mrg 		release_defs (def);
    637  1.1  mrg 	      }
    638  1.1  mrg 
    639  1.1  mrg 	  /* Insert the first store at the beginning of the merge BB.  */
    640  1.1  mrg 	  gimple_set_vdef (first_store, gimple_phi_result (phi));
    641  1.1  mrg 	  SSA_NAME_DEF_STMT (gimple_vdef (first_store)) = first_store;
    642  1.1  mrg 	  gimple_phi_set_result (phi, make_ssa_name (gimple_vop (cfun)));
    643  1.1  mrg 	  gimple_set_vuse (first_store, gimple_phi_result (phi));
    644  1.1  mrg 	  gimple_assign_set_rhs1 (first_store, from);
    645  1.1  mrg 	  /* ???  Should we reset first_stores location?  */
    646  1.1  mrg 	  gsi = gsi_after_labels (bb);
    647  1.1  mrg 	  gsi_insert_before (&gsi, first_store, GSI_SAME_STMT);
    648  1.1  mrg 	  sink_stats.commoned++;
    649  1.1  mrg 
    650  1.1  mrg 	  todo |= TODO_cleanup_cfg;
    651  1.1  mrg 	}
    652  1.1  mrg 
    653  1.1  mrg       /* We could now have empty predecessors that we could remove,
    654  1.1  mrg 	 forming a proper CFG for further sinking.  Note that even
    655  1.1  mrg 	 CFG cleanup doesn't do this fully at the moment and it
    656  1.1  mrg 	 doesn't preserve post-dominators in the process either.
    657  1.1  mrg 	 The mergephi pass might do it though.  gcc.dg/tree-ssa/ssa-sink-13.c
    658  1.1  mrg 	 shows this nicely if you disable tail merging or (same effect)
    659  1.1  mrg 	 make the stored values unequal.  */
    660  1.1  mrg     }
    661  1.1  mrg 
    662  1.1  mrg   return todo;
    663  1.1  mrg }
    664  1.1  mrg 
    665  1.1  mrg /* Perform code sinking on BB */
    666  1.1  mrg 
    667  1.1  mrg static unsigned
    668  1.1  mrg sink_code_in_bb (basic_block bb)
    669  1.1  mrg {
    670  1.1  mrg   basic_block son;
    671  1.1  mrg   gimple_stmt_iterator gsi;
    672  1.1  mrg   edge_iterator ei;
    673  1.1  mrg   edge e;
    674  1.1  mrg   bool last = true;
    675  1.1  mrg   unsigned todo = 0;
    676  1.1  mrg 
    677  1.1  mrg   /* Sink common stores from the predecessor through our virtual PHI.  */
    678  1.1  mrg   todo |= sink_common_stores_to_bb (bb);
    679  1.1  mrg 
    680  1.1  mrg   /* If this block doesn't dominate anything, there can't be any place to sink
    681  1.1  mrg      the statements to.  */
    682  1.1  mrg   if (first_dom_son (CDI_DOMINATORS, bb) == NULL)
    683  1.1  mrg     goto earlyout;
    684  1.1  mrg 
    685  1.1  mrg   /* We can't move things across abnormal edges, so don't try.  */
    686  1.1  mrg   FOR_EACH_EDGE (e, ei, bb->succs)
    687  1.1  mrg     if (e->flags & EDGE_ABNORMAL)
    688  1.1  mrg       goto earlyout;
    689  1.1  mrg 
    690  1.1  mrg   for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi);)
    691  1.1  mrg     {
    692  1.1  mrg       gimple *stmt = gsi_stmt (gsi);
    693  1.1  mrg       gimple_stmt_iterator togsi;
    694  1.1  mrg       bool zero_uses_p;
    695  1.1  mrg 
    696  1.1  mrg       if (!statement_sink_location (stmt, bb, &togsi, &zero_uses_p))
    697  1.1  mrg 	{
    698  1.1  mrg 	  gimple_stmt_iterator saved = gsi;
    699  1.1  mrg 	  if (!gsi_end_p (gsi))
    700  1.1  mrg 	    gsi_prev (&gsi);
    701  1.1  mrg 	  /* If we face a dead stmt remove it as it possibly blocks
    702  1.1  mrg 	     sinking of uses.  */
    703  1.1  mrg 	  if (zero_uses_p
    704  1.1  mrg 	      && !gimple_vdef (stmt)
    705  1.1  mrg 	      && (cfun->can_delete_dead_exceptions
    706  1.1  mrg 		  || !stmt_could_throw_p (cfun, stmt)))
    707  1.1  mrg 	    {
    708  1.1  mrg 	      gsi_remove (&saved, true);
    709  1.1  mrg 	      release_defs (stmt);
    710  1.1  mrg 	    }
    711  1.1  mrg 	  else
    712  1.1  mrg 	    last = false;
    713  1.1  mrg 	  continue;
    714  1.1  mrg 	}
    715  1.1  mrg       if (dump_file)
    716  1.1  mrg 	{
    717  1.1  mrg 	  fprintf (dump_file, "Sinking ");
    718  1.1  mrg 	  print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS);
    719  1.1  mrg 	  fprintf (dump_file, " from bb %d to bb %d\n",
    720  1.1  mrg 		   bb->index, (gsi_bb (togsi))->index);
    721  1.1  mrg 	}
    722  1.1  mrg 
    723  1.1  mrg       /* Update virtual operands of statements in the path we
    724  1.1  mrg          do not sink to.  */
    725  1.1  mrg       if (gimple_vdef (stmt))
    726  1.1  mrg 	{
    727  1.1  mrg 	  imm_use_iterator iter;
    728  1.1  mrg 	  use_operand_p use_p;
    729  1.1  mrg 	  gimple *vuse_stmt;
    730  1.1  mrg 
    731  1.1  mrg 	  FOR_EACH_IMM_USE_STMT (vuse_stmt, iter, gimple_vdef (stmt))
    732  1.1  mrg 	    if (gimple_code (vuse_stmt) != GIMPLE_PHI)
    733  1.1  mrg 	      FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
    734  1.1  mrg 		SET_USE (use_p, gimple_vuse (stmt));
    735  1.1  mrg 	}
    736  1.1  mrg 
    737  1.1  mrg       /* If this is the end of the basic block, we need to insert at the end
    738  1.1  mrg          of the basic block.  */
    739  1.1  mrg       if (gsi_end_p (togsi))
    740  1.1  mrg 	gsi_move_to_bb_end (&gsi, gsi_bb (togsi));
    741  1.1  mrg       else
    742  1.1  mrg 	gsi_move_before (&gsi, &togsi);
    743  1.1  mrg 
    744  1.1  mrg       sink_stats.sunk++;
    745  1.1  mrg 
    746  1.1  mrg       /* If we've just removed the last statement of the BB, the
    747  1.1  mrg 	 gsi_end_p() test below would fail, but gsi_prev() would have
    748  1.1  mrg 	 succeeded, and we want it to succeed.  So we keep track of
    749  1.1  mrg 	 whether we're at the last statement and pick up the new last
    750  1.1  mrg 	 statement.  */
    751  1.1  mrg       if (last)
    752  1.1  mrg 	{
    753  1.1  mrg 	  gsi = gsi_last_bb (bb);
    754  1.1  mrg 	  continue;
    755  1.1  mrg 	}
    756  1.1  mrg 
    757  1.1  mrg       last = false;
    758  1.1  mrg       if (!gsi_end_p (gsi))
    759  1.1  mrg 	gsi_prev (&gsi);
    760  1.1  mrg 
    761  1.1  mrg     }
    762  1.1  mrg  earlyout:
    763  1.1  mrg   for (son = first_dom_son (CDI_POST_DOMINATORS, bb);
    764  1.1  mrg        son;
    765  1.1  mrg        son = next_dom_son (CDI_POST_DOMINATORS, son))
    766  1.1  mrg     {
    767  1.1  mrg       todo |= sink_code_in_bb (son);
    768  1.1  mrg     }
    769  1.1  mrg 
    770  1.1  mrg   return todo;
    771  1.1  mrg }
    772  1.1  mrg 
    773  1.1  mrg /* Perform code sinking.
    774  1.1  mrg    This moves code down the flowgraph when we know it would be
    775  1.1  mrg    profitable to do so, or it wouldn't increase the number of
    776  1.1  mrg    executions of the statement.
    777  1.1  mrg 
    778  1.1  mrg    IE given
    779  1.1  mrg 
    780  1.1  mrg    a_1 = b + c;
    781  1.1  mrg    if (<something>)
    782  1.1  mrg    {
    783  1.1  mrg    }
    784  1.1  mrg    else
    785  1.1  mrg    {
    786  1.1  mrg      foo (&b, &c);
    787  1.1  mrg      a_5 = b + c;
    788  1.1  mrg    }
    789  1.1  mrg    a_6 = PHI (a_5, a_1);
    790  1.1  mrg    USE a_6.
    791  1.1  mrg 
    792  1.1  mrg    we'll transform this into:
    793  1.1  mrg 
    794  1.1  mrg    if (<something>)
    795  1.1  mrg    {
    796  1.1  mrg       a_1 = b + c;
    797  1.1  mrg    }
    798  1.1  mrg    else
    799  1.1  mrg    {
    800  1.1  mrg       foo (&b, &c);
    801  1.1  mrg       a_5 = b + c;
    802  1.1  mrg    }
    803  1.1  mrg    a_6 = PHI (a_5, a_1);
    804  1.1  mrg    USE a_6.
    805  1.1  mrg 
    806  1.1  mrg    Note that this reduces the number of computations of a = b + c to 1
    807  1.1  mrg    when we take the else edge, instead of 2.
    808  1.1  mrg */
    809  1.1  mrg namespace {
    810  1.1  mrg 
    811  1.1  mrg const pass_data pass_data_sink_code =
    812  1.1  mrg {
    813  1.1  mrg   GIMPLE_PASS, /* type */
    814  1.1  mrg   "sink", /* name */
    815  1.1  mrg   OPTGROUP_NONE, /* optinfo_flags */
    816  1.1  mrg   TV_TREE_SINK, /* tv_id */
    817  1.1  mrg   /* PROP_no_crit_edges is ensured by running split_edges_for_insertion in
    818  1.1  mrg      pass_data_sink_code::execute ().  */
    819  1.1  mrg   ( PROP_cfg | PROP_ssa ), /* properties_required */
    820  1.1  mrg   0, /* properties_provided */
    821  1.1  mrg   0, /* properties_destroyed */
    822  1.1  mrg   0, /* todo_flags_start */
    823  1.1  mrg   TODO_update_ssa, /* todo_flags_finish */
    824  1.1  mrg };
    825  1.1  mrg 
    826  1.1  mrg class pass_sink_code : public gimple_opt_pass
    827  1.1  mrg {
    828  1.1  mrg public:
    829  1.1  mrg   pass_sink_code (gcc::context *ctxt)
    830  1.1  mrg     : gimple_opt_pass (pass_data_sink_code, ctxt), unsplit_edges (false)
    831  1.1  mrg   {}
    832  1.1  mrg 
    833  1.1  mrg   /* opt_pass methods: */
    834  1.1  mrg   virtual bool gate (function *) { return flag_tree_sink != 0; }
    835  1.1  mrg   virtual unsigned int execute (function *);
    836  1.1  mrg   opt_pass *clone (void) { return new pass_sink_code (m_ctxt); }
    837  1.1  mrg   void set_pass_param (unsigned n, bool param)
    838  1.1  mrg     {
    839  1.1  mrg       gcc_assert (n == 0);
    840  1.1  mrg       unsplit_edges = param;
    841  1.1  mrg     }
    842  1.1  mrg 
    843  1.1  mrg private:
    844  1.1  mrg   bool unsplit_edges;
    845  1.1  mrg }; // class pass_sink_code
    846  1.1  mrg 
    847  1.1  mrg unsigned int
    848  1.1  mrg pass_sink_code::execute (function *fun)
    849  1.1  mrg {
    850  1.1  mrg   loop_optimizer_init (LOOPS_NORMAL);
    851  1.1  mrg   split_edges_for_insertion ();
    852  1.1  mrg   /* Arrange for the critical edge splitting to be undone if requested.  */
    853  1.1  mrg   unsigned todo = unsplit_edges ? TODO_cleanup_cfg : 0;
    854  1.1  mrg   connect_infinite_loops_to_exit ();
    855  1.1  mrg   memset (&sink_stats, 0, sizeof (sink_stats));
    856  1.1  mrg   calculate_dominance_info (CDI_DOMINATORS);
    857  1.1  mrg   calculate_dominance_info (CDI_POST_DOMINATORS);
    858  1.1  mrg   todo |= sink_code_in_bb (EXIT_BLOCK_PTR_FOR_FN (fun));
    859  1.1  mrg   statistics_counter_event (fun, "Sunk statements", sink_stats.sunk);
    860  1.1  mrg   statistics_counter_event (fun, "Commoned stores", sink_stats.commoned);
    861  1.1  mrg   free_dominance_info (CDI_POST_DOMINATORS);
    862  1.1  mrg   remove_fake_exit_edges ();
    863  1.1  mrg   loop_optimizer_finalize ();
    864  1.1  mrg 
    865  1.1  mrg   return todo;
    866  1.1  mrg }
    867  1.1  mrg 
    868  1.1  mrg } // anon namespace
    869  1.1  mrg 
    870  1.1  mrg gimple_opt_pass *
    871  1.1  mrg make_pass_sink_code (gcc::context *ctxt)
    872  1.1  mrg {
    873  1.1  mrg   return new pass_sink_code (ctxt);
    874  1.1  mrg }
    875