xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/tree-ssa-loop-ivcanon.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg /* Induction variable canonicalization and loop peeling.
2*8feb0f0bSmrg    Copyright (C) 2004-2020 Free Software Foundation, Inc.
31debfc3dSmrg 
41debfc3dSmrg This file is part of GCC.
51debfc3dSmrg 
61debfc3dSmrg GCC is free software; you can redistribute it and/or modify it
71debfc3dSmrg under the terms of the GNU General Public License as published by the
81debfc3dSmrg Free Software Foundation; either version 3, or (at your option) any
91debfc3dSmrg later version.
101debfc3dSmrg 
111debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT
121debfc3dSmrg ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
131debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
141debfc3dSmrg for more details.
151debfc3dSmrg 
161debfc3dSmrg You should have received a copy of the GNU General Public License
171debfc3dSmrg along with GCC; see the file COPYING3.  If not see
181debfc3dSmrg <http://www.gnu.org/licenses/>.  */
191debfc3dSmrg 
201debfc3dSmrg /* This pass detects the loops that iterate a constant number of times,
211debfc3dSmrg    adds a canonical induction variable (step -1, tested against 0)
221debfc3dSmrg    and replaces the exit test.  This enables the less powerful rtl
231debfc3dSmrg    level analysis to use this information.
241debfc3dSmrg 
251debfc3dSmrg    This might spoil the code in some cases (by increasing register pressure).
261debfc3dSmrg    Note that in the case the new variable is not needed, ivopts will get rid
271debfc3dSmrg    of it, so it might only be a problem when there are no other linear induction
281debfc3dSmrg    variables.  In that case the created optimization possibilities are likely
291debfc3dSmrg    to pay up.
301debfc3dSmrg 
311debfc3dSmrg    We also perform
321debfc3dSmrg      - complete unrolling (or peeling) when the loops is rolling few enough
331debfc3dSmrg        times
341debfc3dSmrg      - simple peeling (i.e. copying few initial iterations prior the loop)
351debfc3dSmrg        when number of iteration estimate is known (typically by the profile
361debfc3dSmrg        info).  */
371debfc3dSmrg 
381debfc3dSmrg #include "config.h"
391debfc3dSmrg #include "system.h"
401debfc3dSmrg #include "coretypes.h"
411debfc3dSmrg #include "backend.h"
421debfc3dSmrg #include "tree.h"
431debfc3dSmrg #include "gimple.h"
441debfc3dSmrg #include "cfghooks.h"
451debfc3dSmrg #include "tree-pass.h"
461debfc3dSmrg #include "ssa.h"
471debfc3dSmrg #include "cgraph.h"
481debfc3dSmrg #include "gimple-pretty-print.h"
491debfc3dSmrg #include "fold-const.h"
501debfc3dSmrg #include "profile.h"
511debfc3dSmrg #include "gimple-fold.h"
521debfc3dSmrg #include "tree-eh.h"
531debfc3dSmrg #include "gimple-iterator.h"
541debfc3dSmrg #include "tree-cfg.h"
551debfc3dSmrg #include "tree-ssa-loop-manip.h"
561debfc3dSmrg #include "tree-ssa-loop-niter.h"
571debfc3dSmrg #include "tree-ssa-loop.h"
581debfc3dSmrg #include "tree-into-ssa.h"
591debfc3dSmrg #include "cfgloop.h"
601debfc3dSmrg #include "tree-chrec.h"
611debfc3dSmrg #include "tree-scalar-evolution.h"
621debfc3dSmrg #include "tree-inline.h"
631debfc3dSmrg #include "tree-cfgcleanup.h"
641debfc3dSmrg #include "builtins.h"
65c0a68be4Smrg #include "tree-ssa-sccvn.h"
66*8feb0f0bSmrg #include "dbgcnt.h"
671debfc3dSmrg 
681debfc3dSmrg /* Specifies types of loops that may be unrolled.  */
691debfc3dSmrg 
701debfc3dSmrg enum unroll_level
711debfc3dSmrg {
721debfc3dSmrg   UL_SINGLE_ITER,	/* Only loops that exit immediately in the first
731debfc3dSmrg 			   iteration.  */
741debfc3dSmrg   UL_NO_GROWTH,		/* Only loops whose unrolling will not cause increase
751debfc3dSmrg 			   of code size.  */
761debfc3dSmrg   UL_ALL		/* All suitable loops.  */
771debfc3dSmrg };
781debfc3dSmrg 
791debfc3dSmrg /* Adds a canonical induction variable to LOOP iterating NITER times.  EXIT
80a2dc1f3fSmrg    is the exit edge whose condition is replaced.  The ssa versions of the new
81a2dc1f3fSmrg    IV before and after increment will be stored in VAR_BEFORE and VAR_AFTER
82a2dc1f3fSmrg    if they are not NULL.  */
831debfc3dSmrg 
84a2dc1f3fSmrg void
85*8feb0f0bSmrg create_canonical_iv (class loop *loop, edge exit, tree niter,
86a2dc1f3fSmrg 		     tree *var_before = NULL, tree *var_after = NULL)
871debfc3dSmrg {
881debfc3dSmrg   edge in;
891debfc3dSmrg   tree type, var;
901debfc3dSmrg   gcond *cond;
911debfc3dSmrg   gimple_stmt_iterator incr_at;
921debfc3dSmrg   enum tree_code cmp;
931debfc3dSmrg 
941debfc3dSmrg   if (dump_file && (dump_flags & TDF_DETAILS))
951debfc3dSmrg     {
961debfc3dSmrg       fprintf (dump_file, "Added canonical iv to loop %d, ", loop->num);
971debfc3dSmrg       print_generic_expr (dump_file, niter, TDF_SLIM);
981debfc3dSmrg       fprintf (dump_file, " iterations.\n");
991debfc3dSmrg     }
1001debfc3dSmrg 
1011debfc3dSmrg   cond = as_a <gcond *> (last_stmt (exit->src));
1021debfc3dSmrg   in = EDGE_SUCC (exit->src, 0);
1031debfc3dSmrg   if (in == exit)
1041debfc3dSmrg     in = EDGE_SUCC (exit->src, 1);
1051debfc3dSmrg 
1061debfc3dSmrg   /* Note that we do not need to worry about overflows, since
1071debfc3dSmrg      type of niter is always unsigned and all comparisons are
1081debfc3dSmrg      just for equality/nonequality -- i.e. everything works
1091debfc3dSmrg      with a modulo arithmetics.  */
1101debfc3dSmrg 
1111debfc3dSmrg   type = TREE_TYPE (niter);
1121debfc3dSmrg   niter = fold_build2 (PLUS_EXPR, type,
1131debfc3dSmrg 		       niter,
1141debfc3dSmrg 		       build_int_cst (type, 1));
1151debfc3dSmrg   incr_at = gsi_last_bb (in->src);
1161debfc3dSmrg   create_iv (niter,
1171debfc3dSmrg 	     build_int_cst (type, -1),
1181debfc3dSmrg 	     NULL_TREE, loop,
119a2dc1f3fSmrg 	     &incr_at, false, var_before, &var);
120a2dc1f3fSmrg   if (var_after)
121a2dc1f3fSmrg     *var_after = var;
1221debfc3dSmrg 
1231debfc3dSmrg   cmp = (exit->flags & EDGE_TRUE_VALUE) ? EQ_EXPR : NE_EXPR;
1241debfc3dSmrg   gimple_cond_set_code (cond, cmp);
1251debfc3dSmrg   gimple_cond_set_lhs (cond, var);
1261debfc3dSmrg   gimple_cond_set_rhs (cond, build_int_cst (type, 0));
1271debfc3dSmrg   update_stmt (cond);
1281debfc3dSmrg }
1291debfc3dSmrg 
1301debfc3dSmrg /* Describe size of loop as detected by tree_estimate_loop_size.  */
1311debfc3dSmrg struct loop_size
1321debfc3dSmrg {
1331debfc3dSmrg   /* Number of instructions in the loop.  */
1341debfc3dSmrg   int overall;
1351debfc3dSmrg 
1361debfc3dSmrg   /* Number of instructions that will be likely optimized out in
1371debfc3dSmrg      peeled iterations of loop  (i.e. computation based on induction
1381debfc3dSmrg      variable where induction variable starts at known constant.)  */
1391debfc3dSmrg   int eliminated_by_peeling;
1401debfc3dSmrg 
1411debfc3dSmrg   /* Same statistics for last iteration of loop: it is smaller because
1421debfc3dSmrg      instructions after exit are not executed.  */
1431debfc3dSmrg   int last_iteration;
1441debfc3dSmrg   int last_iteration_eliminated_by_peeling;
1451debfc3dSmrg 
1461debfc3dSmrg   /* If some IV computation will become constant.  */
1471debfc3dSmrg   bool constant_iv;
1481debfc3dSmrg 
1491debfc3dSmrg   /* Number of call stmts that are not a builtin and are pure or const
1501debfc3dSmrg      present on the hot path.  */
1511debfc3dSmrg   int num_pure_calls_on_hot_path;
1521debfc3dSmrg   /* Number of call stmts that are not a builtin and are not pure nor const
1531debfc3dSmrg      present on the hot path.  */
1541debfc3dSmrg   int num_non_pure_calls_on_hot_path;
1551debfc3dSmrg   /* Number of statements other than calls in the loop.  */
1561debfc3dSmrg   int non_call_stmts_on_hot_path;
1571debfc3dSmrg   /* Number of branches seen on the hot path.  */
1581debfc3dSmrg   int num_branches_on_hot_path;
1591debfc3dSmrg };
1601debfc3dSmrg 
1611debfc3dSmrg /* Return true if OP in STMT will be constant after peeling LOOP.  */
1621debfc3dSmrg 
1631debfc3dSmrg static bool
constant_after_peeling(tree op,gimple * stmt,class loop * loop)164*8feb0f0bSmrg constant_after_peeling (tree op, gimple *stmt, class loop *loop)
1651debfc3dSmrg {
166*8feb0f0bSmrg   if (CONSTANT_CLASS_P (op))
1671debfc3dSmrg     return true;
1681debfc3dSmrg 
1691debfc3dSmrg   /* We can still fold accesses to constant arrays when index is known.  */
1701debfc3dSmrg   if (TREE_CODE (op) != SSA_NAME)
1711debfc3dSmrg     {
1721debfc3dSmrg       tree base = op;
1731debfc3dSmrg 
1741debfc3dSmrg       /* First make fast look if we see constant array inside.  */
1751debfc3dSmrg       while (handled_component_p (base))
1761debfc3dSmrg 	base = TREE_OPERAND (base, 0);
1771debfc3dSmrg       if ((DECL_P (base)
1781debfc3dSmrg 	   && ctor_for_folding (base) != error_mark_node)
1791debfc3dSmrg 	  || CONSTANT_CLASS_P (base))
1801debfc3dSmrg 	{
1811debfc3dSmrg 	  /* If so, see if we understand all the indices.  */
1821debfc3dSmrg 	  base = op;
1831debfc3dSmrg 	  while (handled_component_p (base))
1841debfc3dSmrg 	    {
1851debfc3dSmrg 	      if (TREE_CODE (base) == ARRAY_REF
1861debfc3dSmrg 		  && !constant_after_peeling (TREE_OPERAND (base, 1), stmt, loop))
1871debfc3dSmrg 		return false;
1881debfc3dSmrg 	      base = TREE_OPERAND (base, 0);
1891debfc3dSmrg 	    }
1901debfc3dSmrg 	  return true;
1911debfc3dSmrg 	}
1921debfc3dSmrg       return false;
1931debfc3dSmrg     }
1941debfc3dSmrg 
195a2dc1f3fSmrg   /* Induction variables are constants when defined in loop.  */
196a2dc1f3fSmrg   if (loop_containing_stmt (stmt) != loop)
1971debfc3dSmrg     return false;
198a2dc1f3fSmrg   tree ev = analyze_scalar_evolution (loop, op);
199a2dc1f3fSmrg   if (chrec_contains_undetermined (ev)
200a2dc1f3fSmrg       || chrec_contains_symbols (ev))
2011debfc3dSmrg     return false;
2021debfc3dSmrg   return true;
2031debfc3dSmrg }
2041debfc3dSmrg 
2051debfc3dSmrg /* Computes an estimated number of insns in LOOP.
2061debfc3dSmrg    EXIT (if non-NULL) is an exite edge that will be eliminated in all but last
2071debfc3dSmrg    iteration of the loop.
2081debfc3dSmrg    EDGE_TO_CANCEL (if non-NULL) is an non-exit edge eliminated in the last iteration
2091debfc3dSmrg    of loop.
2101debfc3dSmrg    Return results in SIZE, estimate benefits for complete unrolling exiting by EXIT.
2111debfc3dSmrg    Stop estimating after UPPER_BOUND is met.  Return true in this case.  */
2121debfc3dSmrg 
2131debfc3dSmrg static bool
tree_estimate_loop_size(class loop * loop,edge exit,edge edge_to_cancel,struct loop_size * size,int upper_bound)214*8feb0f0bSmrg tree_estimate_loop_size (class loop *loop, edge exit, edge edge_to_cancel,
2151debfc3dSmrg 			 struct loop_size *size, int upper_bound)
2161debfc3dSmrg {
2171debfc3dSmrg   basic_block *body = get_loop_body (loop);
2181debfc3dSmrg   gimple_stmt_iterator gsi;
2191debfc3dSmrg   unsigned int i;
2201debfc3dSmrg   bool after_exit;
2211debfc3dSmrg   vec<basic_block> path = get_loop_hot_path (loop);
2221debfc3dSmrg 
2231debfc3dSmrg   size->overall = 0;
2241debfc3dSmrg   size->eliminated_by_peeling = 0;
2251debfc3dSmrg   size->last_iteration = 0;
2261debfc3dSmrg   size->last_iteration_eliminated_by_peeling = 0;
2271debfc3dSmrg   size->num_pure_calls_on_hot_path = 0;
2281debfc3dSmrg   size->num_non_pure_calls_on_hot_path = 0;
2291debfc3dSmrg   size->non_call_stmts_on_hot_path = 0;
2301debfc3dSmrg   size->num_branches_on_hot_path = 0;
2311debfc3dSmrg   size->constant_iv = 0;
2321debfc3dSmrg 
2331debfc3dSmrg   if (dump_file && (dump_flags & TDF_DETAILS))
2341debfc3dSmrg     fprintf (dump_file, "Estimating sizes for loop %i\n", loop->num);
2351debfc3dSmrg   for (i = 0; i < loop->num_nodes; i++)
2361debfc3dSmrg     {
2371debfc3dSmrg       if (edge_to_cancel && body[i] != edge_to_cancel->src
2381debfc3dSmrg 	  && dominated_by_p (CDI_DOMINATORS, body[i], edge_to_cancel->src))
2391debfc3dSmrg 	after_exit = true;
2401debfc3dSmrg       else
2411debfc3dSmrg 	after_exit = false;
2421debfc3dSmrg       if (dump_file && (dump_flags & TDF_DETAILS))
2431debfc3dSmrg 	fprintf (dump_file, " BB: %i, after_exit: %i\n", body[i]->index,
2441debfc3dSmrg 		 after_exit);
2451debfc3dSmrg 
2461debfc3dSmrg       for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
2471debfc3dSmrg 	{
2481debfc3dSmrg 	  gimple *stmt = gsi_stmt (gsi);
2491debfc3dSmrg 	  int num = estimate_num_insns (stmt, &eni_size_weights);
2501debfc3dSmrg 	  bool likely_eliminated = false;
2511debfc3dSmrg 	  bool likely_eliminated_last = false;
2521debfc3dSmrg 	  bool likely_eliminated_peeled = false;
2531debfc3dSmrg 
2541debfc3dSmrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
2551debfc3dSmrg 	    {
2561debfc3dSmrg 	      fprintf (dump_file, "  size: %3i ", num);
257a2dc1f3fSmrg 	      print_gimple_stmt (dump_file, gsi_stmt (gsi), 0);
2581debfc3dSmrg 	    }
2591debfc3dSmrg 
2601debfc3dSmrg 	  /* Look for reasons why we might optimize this stmt away. */
2611debfc3dSmrg 
2621debfc3dSmrg 	  if (!gimple_has_side_effects (stmt))
2631debfc3dSmrg 	    {
2641debfc3dSmrg 	      /* Exit conditional.  */
2651debfc3dSmrg 	      if (exit && body[i] == exit->src
2661debfc3dSmrg 		  && stmt == last_stmt (exit->src))
2671debfc3dSmrg 		{
2681debfc3dSmrg 		  if (dump_file && (dump_flags & TDF_DETAILS))
2691debfc3dSmrg 		    fprintf (dump_file, "   Exit condition will be eliminated "
2701debfc3dSmrg 			     "in peeled copies.\n");
2711debfc3dSmrg 		  likely_eliminated_peeled = true;
2721debfc3dSmrg 		}
2731debfc3dSmrg 	      if (edge_to_cancel && body[i] == edge_to_cancel->src
2741debfc3dSmrg 		  && stmt == last_stmt (edge_to_cancel->src))
2751debfc3dSmrg 		{
2761debfc3dSmrg 		  if (dump_file && (dump_flags & TDF_DETAILS))
2771debfc3dSmrg 		    fprintf (dump_file, "   Exit condition will be eliminated "
2781debfc3dSmrg 			     "in last copy.\n");
2791debfc3dSmrg 		  likely_eliminated_last = true;
2801debfc3dSmrg 		}
2811debfc3dSmrg 	      /* Sets of IV variables  */
2821debfc3dSmrg 	      if (gimple_code (stmt) == GIMPLE_ASSIGN
2831debfc3dSmrg 		  && constant_after_peeling (gimple_assign_lhs (stmt), stmt, loop))
2841debfc3dSmrg 		{
2851debfc3dSmrg 		  if (dump_file && (dump_flags & TDF_DETAILS))
2861debfc3dSmrg 		    fprintf (dump_file, "   Induction variable computation will"
2871debfc3dSmrg 			     " be folded away.\n");
2881debfc3dSmrg 		  likely_eliminated = true;
2891debfc3dSmrg 		}
2901debfc3dSmrg 	      /* Assignments of IV variables.  */
2911debfc3dSmrg 	      else if (gimple_code (stmt) == GIMPLE_ASSIGN
2921debfc3dSmrg 		       && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
2931debfc3dSmrg 		       && constant_after_peeling (gimple_assign_rhs1 (stmt),
2941debfc3dSmrg 						  stmt, loop)
2951debfc3dSmrg 		       && (gimple_assign_rhs_class (stmt) != GIMPLE_BINARY_RHS
2961debfc3dSmrg 			   || constant_after_peeling (gimple_assign_rhs2 (stmt),
297*8feb0f0bSmrg 						      stmt, loop))
298*8feb0f0bSmrg 		       && gimple_assign_rhs_class (stmt) != GIMPLE_TERNARY_RHS)
2991debfc3dSmrg 		{
3001debfc3dSmrg 		  size->constant_iv = true;
3011debfc3dSmrg 		  if (dump_file && (dump_flags & TDF_DETAILS))
3021debfc3dSmrg 		    fprintf (dump_file,
3031debfc3dSmrg 			     "   Constant expression will be folded away.\n");
3041debfc3dSmrg 		  likely_eliminated = true;
3051debfc3dSmrg 		}
3061debfc3dSmrg 	      /* Conditionals.  */
3071debfc3dSmrg 	      else if ((gimple_code (stmt) == GIMPLE_COND
3081debfc3dSmrg 			&& constant_after_peeling (gimple_cond_lhs (stmt), stmt,
3091debfc3dSmrg 						   loop)
3101debfc3dSmrg 			&& constant_after_peeling (gimple_cond_rhs (stmt), stmt,
3111debfc3dSmrg 						   loop)
3121debfc3dSmrg 			/* We don't simplify all constant compares so make sure
3131debfc3dSmrg 			   they are not both constant already.  See PR70288.  */
3141debfc3dSmrg 			&& (! is_gimple_min_invariant (gimple_cond_lhs (stmt))
3151debfc3dSmrg 			    || ! is_gimple_min_invariant
3161debfc3dSmrg 				 (gimple_cond_rhs (stmt))))
3171debfc3dSmrg 		       || (gimple_code (stmt) == GIMPLE_SWITCH
3181debfc3dSmrg 			   && constant_after_peeling (gimple_switch_index (
3191debfc3dSmrg 							as_a <gswitch *>
3201debfc3dSmrg 							  (stmt)),
3211debfc3dSmrg 						      stmt, loop)
3221debfc3dSmrg 			   && ! is_gimple_min_invariant
3231debfc3dSmrg 				   (gimple_switch_index
3241debfc3dSmrg 				      (as_a <gswitch *> (stmt)))))
3251debfc3dSmrg 		{
3261debfc3dSmrg 		  if (dump_file && (dump_flags & TDF_DETAILS))
3271debfc3dSmrg 		    fprintf (dump_file, "   Constant conditional.\n");
3281debfc3dSmrg 		  likely_eliminated = true;
3291debfc3dSmrg 		}
3301debfc3dSmrg 	    }
3311debfc3dSmrg 
3321debfc3dSmrg 	  size->overall += num;
3331debfc3dSmrg 	  if (likely_eliminated || likely_eliminated_peeled)
3341debfc3dSmrg 	    size->eliminated_by_peeling += num;
3351debfc3dSmrg 	  if (!after_exit)
3361debfc3dSmrg 	    {
3371debfc3dSmrg 	      size->last_iteration += num;
3381debfc3dSmrg 	      if (likely_eliminated || likely_eliminated_last)
3391debfc3dSmrg 		size->last_iteration_eliminated_by_peeling += num;
3401debfc3dSmrg 	    }
3411debfc3dSmrg 	  if ((size->overall * 3 / 2 - size->eliminated_by_peeling
3421debfc3dSmrg 	      - size->last_iteration_eliminated_by_peeling) > upper_bound)
3431debfc3dSmrg 	    {
3441debfc3dSmrg               free (body);
3451debfc3dSmrg 	      path.release ();
3461debfc3dSmrg 	      return true;
3471debfc3dSmrg 	    }
3481debfc3dSmrg 	}
3491debfc3dSmrg     }
3501debfc3dSmrg   while (path.length ())
3511debfc3dSmrg     {
3521debfc3dSmrg       basic_block bb = path.pop ();
3531debfc3dSmrg       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3541debfc3dSmrg 	{
3551debfc3dSmrg 	  gimple *stmt = gsi_stmt (gsi);
3561debfc3dSmrg 	  if (gimple_code (stmt) == GIMPLE_CALL
3571debfc3dSmrg 	      && !gimple_inexpensive_call_p (as_a <gcall *>  (stmt)))
3581debfc3dSmrg 	    {
3591debfc3dSmrg 	      int flags = gimple_call_flags (stmt);
3601debfc3dSmrg 	      if (flags & (ECF_PURE | ECF_CONST))
3611debfc3dSmrg 		size->num_pure_calls_on_hot_path++;
3621debfc3dSmrg 	      else
3631debfc3dSmrg 		size->num_non_pure_calls_on_hot_path++;
3641debfc3dSmrg 	      size->num_branches_on_hot_path ++;
3651debfc3dSmrg 	    }
3661debfc3dSmrg 	  /* Count inexpensive calls as non-calls, because they will likely
3671debfc3dSmrg 	     expand inline.  */
3681debfc3dSmrg 	  else if (gimple_code (stmt) != GIMPLE_DEBUG)
3691debfc3dSmrg 	    size->non_call_stmts_on_hot_path++;
3701debfc3dSmrg 	  if (((gimple_code (stmt) == GIMPLE_COND
3711debfc3dSmrg 	        && (!constant_after_peeling (gimple_cond_lhs (stmt), stmt, loop)
372a2dc1f3fSmrg 		    || !constant_after_peeling (gimple_cond_rhs (stmt), stmt,
3731debfc3dSmrg 						loop)))
3741debfc3dSmrg 	       || (gimple_code (stmt) == GIMPLE_SWITCH
3751debfc3dSmrg 		   && !constant_after_peeling (gimple_switch_index (
3761debfc3dSmrg 						 as_a <gswitch *> (stmt)),
3771debfc3dSmrg 					       stmt, loop)))
3781debfc3dSmrg 	      && (!exit || bb != exit->src))
3791debfc3dSmrg 	    size->num_branches_on_hot_path++;
3801debfc3dSmrg 	}
3811debfc3dSmrg     }
3821debfc3dSmrg   path.release ();
3831debfc3dSmrg   if (dump_file && (dump_flags & TDF_DETAILS))
3841debfc3dSmrg     fprintf (dump_file, "size: %i-%i, last_iteration: %i-%i\n", size->overall,
3851debfc3dSmrg     	     size->eliminated_by_peeling, size->last_iteration,
3861debfc3dSmrg 	     size->last_iteration_eliminated_by_peeling);
3871debfc3dSmrg 
3881debfc3dSmrg   free (body);
3891debfc3dSmrg   return false;
3901debfc3dSmrg }
3911debfc3dSmrg 
3921debfc3dSmrg /* Estimate number of insns of completely unrolled loop.
3931debfc3dSmrg    It is (NUNROLL + 1) * size of loop body with taking into account
3941debfc3dSmrg    the fact that in last copy everything after exit conditional
3951debfc3dSmrg    is dead and that some instructions will be eliminated after
3961debfc3dSmrg    peeling.
3971debfc3dSmrg 
3981debfc3dSmrg    Loop body is likely going to simplify further, this is difficult
3991debfc3dSmrg    to guess, we just decrease the result by 1/3.  */
4001debfc3dSmrg 
4011debfc3dSmrg static unsigned HOST_WIDE_INT
estimated_unrolled_size(struct loop_size * size,unsigned HOST_WIDE_INT nunroll)4021debfc3dSmrg estimated_unrolled_size (struct loop_size *size,
4031debfc3dSmrg 			 unsigned HOST_WIDE_INT nunroll)
4041debfc3dSmrg {
4051debfc3dSmrg   HOST_WIDE_INT unr_insns = ((nunroll)
4061debfc3dSmrg   			     * (HOST_WIDE_INT) (size->overall
4071debfc3dSmrg 			     			- size->eliminated_by_peeling));
4081debfc3dSmrg   if (!nunroll)
4091debfc3dSmrg     unr_insns = 0;
4101debfc3dSmrg   unr_insns += size->last_iteration - size->last_iteration_eliminated_by_peeling;
4111debfc3dSmrg 
4121debfc3dSmrg   unr_insns = unr_insns * 2 / 3;
4131debfc3dSmrg   if (unr_insns <= 0)
4141debfc3dSmrg     unr_insns = 1;
4151debfc3dSmrg 
4161debfc3dSmrg   return unr_insns;
4171debfc3dSmrg }
4181debfc3dSmrg 
4191debfc3dSmrg /* Loop LOOP is known to not loop.  See if there is an edge in the loop
4201debfc3dSmrg    body that can be remove to make the loop to always exit and at
4211debfc3dSmrg    the same time it does not make any code potentially executed
4221debfc3dSmrg    during the last iteration dead.
4231debfc3dSmrg 
4241debfc3dSmrg    After complete unrolling we still may get rid of the conditional
4251debfc3dSmrg    on the exit in the last copy even if we have no idea what it does.
4261debfc3dSmrg    This is quite common case for loops of form
4271debfc3dSmrg 
4281debfc3dSmrg      int a[5];
4291debfc3dSmrg      for (i=0;i<b;i++)
4301debfc3dSmrg        a[i]=0;
4311debfc3dSmrg 
4321debfc3dSmrg    Here we prove the loop to iterate 5 times but we do not know
4331debfc3dSmrg    it from induction variable.
4341debfc3dSmrg 
4351debfc3dSmrg    For now we handle only simple case where there is exit condition
4361debfc3dSmrg    just before the latch block and the latch block contains no statements
4371debfc3dSmrg    with side effect that may otherwise terminate the execution of loop
4381debfc3dSmrg    (such as by EH or by terminating the program or longjmp).
4391debfc3dSmrg 
4401debfc3dSmrg    In the general case we may want to cancel the paths leading to statements
4411debfc3dSmrg    loop-niter identified as having undefined effect in the last iteration.
4421debfc3dSmrg    The other cases are hopefully rare and will be cleaned up later.  */
4431debfc3dSmrg 
4441debfc3dSmrg static edge
loop_edge_to_cancel(class loop * loop)445*8feb0f0bSmrg loop_edge_to_cancel (class loop *loop)
4461debfc3dSmrg {
4471debfc3dSmrg   vec<edge> exits;
4481debfc3dSmrg   unsigned i;
4491debfc3dSmrg   edge edge_to_cancel;
4501debfc3dSmrg   gimple_stmt_iterator gsi;
4511debfc3dSmrg 
4521debfc3dSmrg   /* We want only one predecestor of the loop.  */
4531debfc3dSmrg   if (EDGE_COUNT (loop->latch->preds) > 1)
4541debfc3dSmrg     return NULL;
4551debfc3dSmrg 
4561debfc3dSmrg   exits = get_loop_exit_edges (loop);
4571debfc3dSmrg 
4581debfc3dSmrg   FOR_EACH_VEC_ELT (exits, i, edge_to_cancel)
4591debfc3dSmrg     {
4601debfc3dSmrg        /* Find the other edge than the loop exit
4611debfc3dSmrg           leaving the conditoinal.  */
4621debfc3dSmrg        if (EDGE_COUNT (edge_to_cancel->src->succs) != 2)
4631debfc3dSmrg          continue;
4641debfc3dSmrg        if (EDGE_SUCC (edge_to_cancel->src, 0) == edge_to_cancel)
4651debfc3dSmrg          edge_to_cancel = EDGE_SUCC (edge_to_cancel->src, 1);
4661debfc3dSmrg        else
4671debfc3dSmrg          edge_to_cancel = EDGE_SUCC (edge_to_cancel->src, 0);
4681debfc3dSmrg 
4691debfc3dSmrg       /* We only can handle conditionals.  */
4701debfc3dSmrg       if (!(edge_to_cancel->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE)))
4711debfc3dSmrg 	continue;
4721debfc3dSmrg 
4731debfc3dSmrg       /* We should never have conditionals in the loop latch. */
4741debfc3dSmrg       gcc_assert (edge_to_cancel->dest != loop->header);
4751debfc3dSmrg 
4761debfc3dSmrg       /* Check that it leads to loop latch.  */
4771debfc3dSmrg       if (edge_to_cancel->dest != loop->latch)
4781debfc3dSmrg         continue;
4791debfc3dSmrg 
4801debfc3dSmrg       exits.release ();
4811debfc3dSmrg 
4821debfc3dSmrg       /* Verify that the code in loop latch does nothing that may end program
4831debfc3dSmrg          execution without really reaching the exit.  This may include
4841debfc3dSmrg 	 non-pure/const function calls, EH statements, volatile ASMs etc.  */
4851debfc3dSmrg       for (gsi = gsi_start_bb (loop->latch); !gsi_end_p (gsi); gsi_next (&gsi))
4861debfc3dSmrg 	if (gimple_has_side_effects (gsi_stmt (gsi)))
4871debfc3dSmrg 	   return NULL;
4881debfc3dSmrg       return edge_to_cancel;
4891debfc3dSmrg     }
4901debfc3dSmrg   exits.release ();
4911debfc3dSmrg   return NULL;
4921debfc3dSmrg }
4931debfc3dSmrg 
4941debfc3dSmrg /* Remove all tests for exits that are known to be taken after LOOP was
4951debfc3dSmrg    peeled NPEELED times. Put gcc_unreachable before every statement
4961debfc3dSmrg    known to not be executed.  */
4971debfc3dSmrg 
4981debfc3dSmrg static bool
remove_exits_and_undefined_stmts(class loop * loop,unsigned int npeeled)499*8feb0f0bSmrg remove_exits_and_undefined_stmts (class loop *loop, unsigned int npeeled)
5001debfc3dSmrg {
501*8feb0f0bSmrg   class nb_iter_bound *elt;
5021debfc3dSmrg   bool changed = false;
5031debfc3dSmrg 
5041debfc3dSmrg   for (elt = loop->bounds; elt; elt = elt->next)
5051debfc3dSmrg     {
5061debfc3dSmrg       /* If statement is known to be undefined after peeling, turn it
5071debfc3dSmrg 	 into unreachable (or trap when debugging experience is supposed
5081debfc3dSmrg 	 to be good).  */
5091debfc3dSmrg       if (!elt->is_exit
5101debfc3dSmrg 	  && wi::ltu_p (elt->bound, npeeled))
5111debfc3dSmrg 	{
5121debfc3dSmrg 	  gimple_stmt_iterator gsi = gsi_for_stmt (elt->stmt);
5131debfc3dSmrg 	  gcall *stmt = gimple_build_call
5141debfc3dSmrg 	      (builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0);
5151debfc3dSmrg 	  gimple_set_location (stmt, gimple_location (elt->stmt));
5161debfc3dSmrg 	  gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
5171debfc3dSmrg 	  split_block (gimple_bb (stmt), stmt);
5181debfc3dSmrg 	  changed = true;
5191debfc3dSmrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
5201debfc3dSmrg 	    {
5211debfc3dSmrg 	      fprintf (dump_file, "Forced statement unreachable: ");
522a2dc1f3fSmrg 	      print_gimple_stmt (dump_file, elt->stmt, 0);
5231debfc3dSmrg 	    }
5241debfc3dSmrg 	}
5251debfc3dSmrg       /* If we know the exit will be taken after peeling, update.  */
5261debfc3dSmrg       else if (elt->is_exit
5271debfc3dSmrg 	       && wi::leu_p (elt->bound, npeeled))
5281debfc3dSmrg 	{
5291debfc3dSmrg 	  basic_block bb = gimple_bb (elt->stmt);
5301debfc3dSmrg 	  edge exit_edge = EDGE_SUCC (bb, 0);
5311debfc3dSmrg 
5321debfc3dSmrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
5331debfc3dSmrg 	    {
5341debfc3dSmrg 	      fprintf (dump_file, "Forced exit to be taken: ");
535a2dc1f3fSmrg 	      print_gimple_stmt (dump_file, elt->stmt, 0);
5361debfc3dSmrg 	    }
5371debfc3dSmrg 	  if (!loop_exit_edge_p (loop, exit_edge))
5381debfc3dSmrg 	    exit_edge = EDGE_SUCC (bb, 1);
539a2dc1f3fSmrg 	  exit_edge->probability = profile_probability::always ();
5401debfc3dSmrg 	  gcc_checking_assert (loop_exit_edge_p (loop, exit_edge));
5411debfc3dSmrg 	  gcond *cond_stmt = as_a <gcond *> (elt->stmt);
5421debfc3dSmrg 	  if (exit_edge->flags & EDGE_TRUE_VALUE)
5431debfc3dSmrg 	    gimple_cond_make_true (cond_stmt);
5441debfc3dSmrg 	  else
5451debfc3dSmrg 	    gimple_cond_make_false (cond_stmt);
5461debfc3dSmrg 	  update_stmt (cond_stmt);
5471debfc3dSmrg 	  changed = true;
5481debfc3dSmrg 	}
5491debfc3dSmrg     }
5501debfc3dSmrg   return changed;
5511debfc3dSmrg }
5521debfc3dSmrg 
5531debfc3dSmrg /* Remove all exits that are known to be never taken because of the loop bound
5541debfc3dSmrg    discovered.  */
5551debfc3dSmrg 
5561debfc3dSmrg static bool
remove_redundant_iv_tests(class loop * loop)557*8feb0f0bSmrg remove_redundant_iv_tests (class loop *loop)
5581debfc3dSmrg {
559*8feb0f0bSmrg   class nb_iter_bound *elt;
5601debfc3dSmrg   bool changed = false;
5611debfc3dSmrg 
5621debfc3dSmrg   if (!loop->any_upper_bound)
5631debfc3dSmrg     return false;
5641debfc3dSmrg   for (elt = loop->bounds; elt; elt = elt->next)
5651debfc3dSmrg     {
5661debfc3dSmrg       /* Exit is pointless if it won't be taken before loop reaches
5671debfc3dSmrg 	 upper bound.  */
5681debfc3dSmrg       if (elt->is_exit && loop->any_upper_bound
5691debfc3dSmrg           && wi::ltu_p (loop->nb_iterations_upper_bound, elt->bound))
5701debfc3dSmrg 	{
5711debfc3dSmrg 	  basic_block bb = gimple_bb (elt->stmt);
5721debfc3dSmrg 	  edge exit_edge = EDGE_SUCC (bb, 0);
573*8feb0f0bSmrg 	  class tree_niter_desc niter;
5741debfc3dSmrg 
5751debfc3dSmrg 	  if (!loop_exit_edge_p (loop, exit_edge))
5761debfc3dSmrg 	    exit_edge = EDGE_SUCC (bb, 1);
5771debfc3dSmrg 
5781debfc3dSmrg 	  /* Only when we know the actual number of iterations, not
5791debfc3dSmrg 	     just a bound, we can remove the exit.  */
5801debfc3dSmrg 	  if (!number_of_iterations_exit (loop, exit_edge,
5811debfc3dSmrg 					  &niter, false, false)
5821debfc3dSmrg 	      || !integer_onep (niter.assumptions)
5831debfc3dSmrg 	      || !integer_zerop (niter.may_be_zero)
5841debfc3dSmrg 	      || !niter.niter
5851debfc3dSmrg 	      || TREE_CODE (niter.niter) != INTEGER_CST
5861debfc3dSmrg 	      || !wi::ltu_p (loop->nb_iterations_upper_bound,
5871debfc3dSmrg 			     wi::to_widest (niter.niter)))
5881debfc3dSmrg 	    continue;
5891debfc3dSmrg 
5901debfc3dSmrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
5911debfc3dSmrg 	    {
5921debfc3dSmrg 	      fprintf (dump_file, "Removed pointless exit: ");
593a2dc1f3fSmrg 	      print_gimple_stmt (dump_file, elt->stmt, 0);
5941debfc3dSmrg 	    }
5951debfc3dSmrg 	  gcond *cond_stmt = as_a <gcond *> (elt->stmt);
5961debfc3dSmrg 	  if (exit_edge->flags & EDGE_TRUE_VALUE)
5971debfc3dSmrg 	    gimple_cond_make_false (cond_stmt);
5981debfc3dSmrg 	  else
5991debfc3dSmrg 	    gimple_cond_make_true (cond_stmt);
6001debfc3dSmrg 	  update_stmt (cond_stmt);
6011debfc3dSmrg 	  changed = true;
6021debfc3dSmrg 	}
6031debfc3dSmrg     }
6041debfc3dSmrg   return changed;
6051debfc3dSmrg }
6061debfc3dSmrg 
6071debfc3dSmrg /* Stores loops that will be unlooped and edges that will be removed
6081debfc3dSmrg    after we process whole loop tree. */
6091debfc3dSmrg static vec<loop_p> loops_to_unloop;
6101debfc3dSmrg static vec<int> loops_to_unloop_nunroll;
6111debfc3dSmrg static vec<edge> edges_to_remove;
6121debfc3dSmrg /* Stores loops that has been peeled.  */
6131debfc3dSmrg static bitmap peeled_loops;
6141debfc3dSmrg 
6151debfc3dSmrg /* Cancel all fully unrolled loops by putting __builtin_unreachable
6161debfc3dSmrg    on the latch edge.
6171debfc3dSmrg    We do it after all unrolling since unlooping moves basic blocks
6181debfc3dSmrg    across loop boundaries trashing loop closed SSA form as well
6191debfc3dSmrg    as SCEV info needed to be intact during unrolling.
6201debfc3dSmrg 
6211debfc3dSmrg    IRRED_INVALIDATED is used to bookkeep if information about
6221debfc3dSmrg    irreducible regions may become invalid as a result
6231debfc3dSmrg    of the transformation.
6241debfc3dSmrg    LOOP_CLOSED_SSA_INVALIDATED is used to bookkepp the case
6251debfc3dSmrg    when we need to go into loop closed SSA form.  */
6261debfc3dSmrg 
6271debfc3dSmrg static void
unloop_loops(bitmap loop_closed_ssa_invalidated,bool * irred_invalidated)6281debfc3dSmrg unloop_loops (bitmap loop_closed_ssa_invalidated,
6291debfc3dSmrg 	      bool *irred_invalidated)
6301debfc3dSmrg {
6311debfc3dSmrg   while (loops_to_unloop.length ())
6321debfc3dSmrg     {
633*8feb0f0bSmrg       class loop *loop = loops_to_unloop.pop ();
6341debfc3dSmrg       int n_unroll = loops_to_unloop_nunroll.pop ();
6351debfc3dSmrg       basic_block latch = loop->latch;
6361debfc3dSmrg       edge latch_edge = loop_latch_edge (loop);
6371debfc3dSmrg       int flags = latch_edge->flags;
6381debfc3dSmrg       location_t locus = latch_edge->goto_locus;
6391debfc3dSmrg       gcall *stmt;
6401debfc3dSmrg       gimple_stmt_iterator gsi;
6411debfc3dSmrg 
6421debfc3dSmrg       remove_exits_and_undefined_stmts (loop, n_unroll);
6431debfc3dSmrg 
6441debfc3dSmrg       /* Unloop destroys the latch edge.  */
6451debfc3dSmrg       unloop (loop, irred_invalidated, loop_closed_ssa_invalidated);
6461debfc3dSmrg 
6471debfc3dSmrg       /* Create new basic block for the latch edge destination and wire
6481debfc3dSmrg 	 it in.  */
6491debfc3dSmrg       stmt = gimple_build_call (builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0);
6501debfc3dSmrg       latch_edge = make_edge (latch, create_basic_block (NULL, NULL, latch), flags);
651a2dc1f3fSmrg       latch_edge->probability = profile_probability::never ();
6521debfc3dSmrg       latch_edge->flags |= flags;
6531debfc3dSmrg       latch_edge->goto_locus = locus;
6541debfc3dSmrg 
6551debfc3dSmrg       add_bb_to_loop (latch_edge->dest, current_loops->tree_root);
656a2dc1f3fSmrg       latch_edge->dest->count = profile_count::zero ();
6571debfc3dSmrg       set_immediate_dominator (CDI_DOMINATORS, latch_edge->dest, latch_edge->src);
6581debfc3dSmrg 
6591debfc3dSmrg       gsi = gsi_start_bb (latch_edge->dest);
6601debfc3dSmrg       gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
6611debfc3dSmrg     }
6621debfc3dSmrg   loops_to_unloop.release ();
6631debfc3dSmrg   loops_to_unloop_nunroll.release ();
6641debfc3dSmrg 
665a2dc1f3fSmrg   /* Remove edges in peeled copies.  Given remove_path removes dominated
666a2dc1f3fSmrg      regions we need to cope with removal of already removed paths.  */
6671debfc3dSmrg   unsigned i;
6681debfc3dSmrg   edge e;
669a2dc1f3fSmrg   auto_vec<int, 20> src_bbs;
670a2dc1f3fSmrg   src_bbs.reserve_exact (edges_to_remove.length ());
6711debfc3dSmrg   FOR_EACH_VEC_ELT (edges_to_remove, i, e)
672a2dc1f3fSmrg     src_bbs.quick_push (e->src->index);
673a2dc1f3fSmrg   FOR_EACH_VEC_ELT (edges_to_remove, i, e)
674a2dc1f3fSmrg     if (BASIC_BLOCK_FOR_FN (cfun, src_bbs[i]))
6751debfc3dSmrg       {
676a2dc1f3fSmrg 	bool ok = remove_path (e, irred_invalidated,
677a2dc1f3fSmrg 			       loop_closed_ssa_invalidated);
6781debfc3dSmrg 	gcc_assert (ok);
6791debfc3dSmrg       }
6801debfc3dSmrg   edges_to_remove.release ();
6811debfc3dSmrg }
6821debfc3dSmrg 
6831debfc3dSmrg /* Tries to unroll LOOP completely, i.e. NITER times.
6841debfc3dSmrg    UL determines which loops we are allowed to unroll.
6851debfc3dSmrg    EXIT is the exit of the loop that should be eliminated.
6861debfc3dSmrg    MAXITER specfy bound on number of iterations, -1 if it is
6871debfc3dSmrg    not known or too large for HOST_WIDE_INT.  The location
6881debfc3dSmrg    LOCUS corresponding to the loop is used when emitting
6891debfc3dSmrg    a summary of the unroll to the dump file.  */
6901debfc3dSmrg 
6911debfc3dSmrg static bool
try_unroll_loop_completely(class loop * loop,edge exit,tree niter,bool may_be_zero,enum unroll_level ul,HOST_WIDE_INT maxiter,dump_user_location_t locus,bool allow_peel)692*8feb0f0bSmrg try_unroll_loop_completely (class loop *loop,
693a2dc1f3fSmrg 			    edge exit, tree niter, bool may_be_zero,
6941debfc3dSmrg 			    enum unroll_level ul,
6951debfc3dSmrg 			    HOST_WIDE_INT maxiter,
696c0a68be4Smrg 			    dump_user_location_t locus, bool allow_peel)
6971debfc3dSmrg {
698a2dc1f3fSmrg   unsigned HOST_WIDE_INT n_unroll = 0;
6991debfc3dSmrg   bool n_unroll_found = false;
7001debfc3dSmrg   edge edge_to_cancel = NULL;
7011debfc3dSmrg 
7021debfc3dSmrg   /* See if we proved number of iterations to be low constant.
7031debfc3dSmrg 
7041debfc3dSmrg      EXIT is an edge that will be removed in all but last iteration of
7051debfc3dSmrg      the loop.
7061debfc3dSmrg 
7071debfc3dSmrg      EDGE_TO_CACNEL is an edge that will be removed from the last iteration
7081debfc3dSmrg      of the unrolled sequence and is expected to make the final loop not
7091debfc3dSmrg      rolling.
7101debfc3dSmrg 
7111debfc3dSmrg      If the number of execution of loop is determined by standard induction
7121debfc3dSmrg      variable test, then EXIT and EDGE_TO_CANCEL are the two edges leaving
7131debfc3dSmrg      from the iv test.  */
7141debfc3dSmrg   if (tree_fits_uhwi_p (niter))
7151debfc3dSmrg     {
7161debfc3dSmrg       n_unroll = tree_to_uhwi (niter);
7171debfc3dSmrg       n_unroll_found = true;
7181debfc3dSmrg       edge_to_cancel = EDGE_SUCC (exit->src, 0);
7191debfc3dSmrg       if (edge_to_cancel == exit)
7201debfc3dSmrg 	edge_to_cancel = EDGE_SUCC (exit->src, 1);
7211debfc3dSmrg     }
7221debfc3dSmrg   /* We do not know the number of iterations and thus we cannot eliminate
7231debfc3dSmrg      the EXIT edge.  */
7241debfc3dSmrg   else
7251debfc3dSmrg     exit = NULL;
7261debfc3dSmrg 
7271debfc3dSmrg   /* See if we can improve our estimate by using recorded loop bounds.  */
728a2dc1f3fSmrg   if ((allow_peel || maxiter == 0 || ul == UL_NO_GROWTH)
729a2dc1f3fSmrg       && maxiter >= 0
7301debfc3dSmrg       && (!n_unroll_found || (unsigned HOST_WIDE_INT)maxiter < n_unroll))
7311debfc3dSmrg     {
7321debfc3dSmrg       n_unroll = maxiter;
7331debfc3dSmrg       n_unroll_found = true;
7341debfc3dSmrg       /* Loop terminates before the IV variable test, so we cannot
7351debfc3dSmrg 	 remove it in the last iteration.  */
7361debfc3dSmrg       edge_to_cancel = NULL;
7371debfc3dSmrg     }
7381debfc3dSmrg 
7391debfc3dSmrg   if (!n_unroll_found)
7401debfc3dSmrg     return false;
7411debfc3dSmrg 
742a2dc1f3fSmrg   if (!loop->unroll
743*8feb0f0bSmrg       && n_unroll > (unsigned) param_max_completely_peel_times)
7441debfc3dSmrg     {
7451debfc3dSmrg       if (dump_file && (dump_flags & TDF_DETAILS))
7461debfc3dSmrg 	fprintf (dump_file, "Not unrolling loop %d "
7471debfc3dSmrg 		 "(--param max-completely-peel-times limit reached).\n",
7481debfc3dSmrg 		 loop->num);
7491debfc3dSmrg       return false;
7501debfc3dSmrg     }
7511debfc3dSmrg 
7521debfc3dSmrg   if (!edge_to_cancel)
7531debfc3dSmrg     edge_to_cancel = loop_edge_to_cancel (loop);
7541debfc3dSmrg 
7551debfc3dSmrg   if (n_unroll)
7561debfc3dSmrg     {
7571debfc3dSmrg       if (ul == UL_SINGLE_ITER)
7581debfc3dSmrg 	return false;
7591debfc3dSmrg 
760a2dc1f3fSmrg       if (loop->unroll)
761a2dc1f3fSmrg 	{
762a2dc1f3fSmrg 	  /* If the unrolling factor is too large, bail out.  */
763a2dc1f3fSmrg 	  if (n_unroll > (unsigned)loop->unroll)
764a2dc1f3fSmrg 	    {
765a2dc1f3fSmrg 	      if (dump_file && (dump_flags & TDF_DETAILS))
766a2dc1f3fSmrg 		fprintf (dump_file,
767a2dc1f3fSmrg 			 "Not unrolling loop %d: "
768a2dc1f3fSmrg 			 "user didn't want it unrolled completely.\n",
769a2dc1f3fSmrg 			 loop->num);
770a2dc1f3fSmrg 	      return false;
771a2dc1f3fSmrg 	    }
772a2dc1f3fSmrg 	}
773a2dc1f3fSmrg       else
774a2dc1f3fSmrg 	{
775a2dc1f3fSmrg 	  struct loop_size size;
7761debfc3dSmrg 	  /* EXIT can be removed only if we are sure it passes first N_UNROLL
7771debfc3dSmrg 	     iterations.  */
7781debfc3dSmrg 	  bool remove_exit = (exit && niter
7791debfc3dSmrg 			      && TREE_CODE (niter) == INTEGER_CST
7801debfc3dSmrg 			      && wi::leu_p (n_unroll, wi::to_widest (niter)));
781a2dc1f3fSmrg 	  bool large
782a2dc1f3fSmrg 	    = tree_estimate_loop_size
7831debfc3dSmrg 		(loop, remove_exit ? exit : NULL, edge_to_cancel, &size,
784*8feb0f0bSmrg 		 param_max_completely_peeled_insns);
7851debfc3dSmrg 	  if (large)
7861debfc3dSmrg 	    {
7871debfc3dSmrg 	      if (dump_file && (dump_flags & TDF_DETAILS))
7881debfc3dSmrg 		fprintf (dump_file, "Not unrolling loop %d: it is too large.\n",
7891debfc3dSmrg 			 loop->num);
7901debfc3dSmrg 	      return false;
7911debfc3dSmrg 	    }
7921debfc3dSmrg 
793a2dc1f3fSmrg 	  unsigned HOST_WIDE_INT ninsns = size.overall;
794a2dc1f3fSmrg 	  unsigned HOST_WIDE_INT unr_insns
795a2dc1f3fSmrg 	    = estimated_unrolled_size (&size, n_unroll);
7961debfc3dSmrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
7971debfc3dSmrg 	    {
7981debfc3dSmrg 	      fprintf (dump_file, "  Loop size: %d\n", (int) ninsns);
7991debfc3dSmrg 	      fprintf (dump_file, "  Estimated size after unrolling: %d\n",
8001debfc3dSmrg 		       (int) unr_insns);
8011debfc3dSmrg 	    }
8021debfc3dSmrg 
803a2dc1f3fSmrg 	  /* If the code is going to shrink, we don't need to be extra
804a2dc1f3fSmrg 	     cautious on guessing if the unrolling is going to be
805a2dc1f3fSmrg 	     profitable.  */
8061debfc3dSmrg 	  if (unr_insns
807a2dc1f3fSmrg 	      /* If there is IV variable that will become constant, we
808a2dc1f3fSmrg 		 save one instruction in the loop prologue we do not
809a2dc1f3fSmrg 		 account otherwise.  */
8101debfc3dSmrg 	      <= ninsns + (size.constant_iv != false))
8111debfc3dSmrg 	    ;
812a2dc1f3fSmrg 	  /* We unroll only inner loops, because we do not consider it
813a2dc1f3fSmrg 	     profitable otheriwse.  We still can cancel loopback edge
814a2dc1f3fSmrg 	     of not rolling loop; this is always a good idea.  */
8151debfc3dSmrg 	  else if (ul == UL_NO_GROWTH)
8161debfc3dSmrg 	    {
8171debfc3dSmrg 	      if (dump_file && (dump_flags & TDF_DETAILS))
8181debfc3dSmrg 		fprintf (dump_file, "Not unrolling loop %d: size would grow.\n",
8191debfc3dSmrg 			 loop->num);
8201debfc3dSmrg 	      return false;
8211debfc3dSmrg 	    }
822a2dc1f3fSmrg 	  /* Outer loops tend to be less interesting candidates for
823a2dc1f3fSmrg 	     complete unrolling unless we can do a lot of propagation
824a2dc1f3fSmrg 	     into the inner loop body.  For now we disable outer loop
825a2dc1f3fSmrg 	     unrolling when the code would grow.  */
8261debfc3dSmrg 	  else if (loop->inner)
8271debfc3dSmrg 	    {
8281debfc3dSmrg 	      if (dump_file && (dump_flags & TDF_DETAILS))
8291debfc3dSmrg 		fprintf (dump_file, "Not unrolling loop %d: "
8301debfc3dSmrg 			 "it is not innermost and code would grow.\n",
8311debfc3dSmrg 			 loop->num);
8321debfc3dSmrg 	      return false;
8331debfc3dSmrg 	    }
8341debfc3dSmrg 	  /* If there is call on a hot path through the loop, then
8351debfc3dSmrg 	     there is most probably not much to optimize.  */
8361debfc3dSmrg 	  else if (size.num_non_pure_calls_on_hot_path)
8371debfc3dSmrg 	    {
8381debfc3dSmrg 	      if (dump_file && (dump_flags & TDF_DETAILS))
8391debfc3dSmrg 		fprintf (dump_file, "Not unrolling loop %d: "
8401debfc3dSmrg 			 "contains call and code would grow.\n",
8411debfc3dSmrg 			 loop->num);
8421debfc3dSmrg 	      return false;
8431debfc3dSmrg 	    }
844a2dc1f3fSmrg 	  /* If there is pure/const call in the function, then we can
845a2dc1f3fSmrg 	     still optimize the unrolled loop body if it contains some
846a2dc1f3fSmrg 	     other interesting code than the calls and code storing or
847a2dc1f3fSmrg 	     cumulating the return value.  */
8481debfc3dSmrg 	  else if (size.num_pure_calls_on_hot_path
849a2dc1f3fSmrg 		   /* One IV increment, one test, one ivtmp store and
850a2dc1f3fSmrg 		      one useful stmt.  That is about minimal loop
8511debfc3dSmrg 		      doing pure call.  */
8521debfc3dSmrg 		   && (size.non_call_stmts_on_hot_path
8531debfc3dSmrg 		       <= 3 + size.num_pure_calls_on_hot_path))
8541debfc3dSmrg 	    {
8551debfc3dSmrg 	      if (dump_file && (dump_flags & TDF_DETAILS))
8561debfc3dSmrg 		fprintf (dump_file, "Not unrolling loop %d: "
8571debfc3dSmrg 			 "contains just pure calls and code would grow.\n",
8581debfc3dSmrg 			 loop->num);
8591debfc3dSmrg 	      return false;
8601debfc3dSmrg 	    }
861a2dc1f3fSmrg 	  /* Complete unrolling is major win when control flow is
862a2dc1f3fSmrg 	     removed and one big basic block is created.  If the loop
863a2dc1f3fSmrg 	     contains control flow the optimization may still be a win
864a2dc1f3fSmrg 	     because of eliminating the loop overhead but it also may
865a2dc1f3fSmrg 	     blow the branch predictor tables.  Limit number of
866a2dc1f3fSmrg 	     branches on the hot path through the peeled sequence.  */
8671debfc3dSmrg 	  else if (size.num_branches_on_hot_path * (int)n_unroll
868*8feb0f0bSmrg 		   > param_max_peel_branches)
8691debfc3dSmrg 	    {
8701debfc3dSmrg 	      if (dump_file && (dump_flags & TDF_DETAILS))
8711debfc3dSmrg 		fprintf (dump_file, "Not unrolling loop %d: "
872a2dc1f3fSmrg 			 "number of branches on hot path in the unrolled "
873a2dc1f3fSmrg 			 "sequence reaches --param max-peel-branches limit.\n",
8741debfc3dSmrg 			 loop->num);
8751debfc3dSmrg 	      return false;
8761debfc3dSmrg 	    }
8771debfc3dSmrg 	  else if (unr_insns
878*8feb0f0bSmrg 		   > (unsigned) param_max_completely_peeled_insns)
8791debfc3dSmrg 	    {
8801debfc3dSmrg 	      if (dump_file && (dump_flags & TDF_DETAILS))
8811debfc3dSmrg 		fprintf (dump_file, "Not unrolling loop %d: "
882a2dc1f3fSmrg 			 "number of insns in the unrolled sequence reaches "
883a2dc1f3fSmrg 			 "--param max-completely-peeled-insns limit.\n",
8841debfc3dSmrg 			 loop->num);
8851debfc3dSmrg 	      return false;
8861debfc3dSmrg 	    }
887a2dc1f3fSmrg 	}
8881debfc3dSmrg 
889*8feb0f0bSmrg       if (!dbg_cnt (gimple_unroll))
890*8feb0f0bSmrg 	return false;
891*8feb0f0bSmrg 
8921debfc3dSmrg       initialize_original_copy_tables ();
8931debfc3dSmrg       auto_sbitmap wont_exit (n_unroll + 1);
8941debfc3dSmrg       if (exit && niter
8951debfc3dSmrg 	  && TREE_CODE (niter) == INTEGER_CST
8961debfc3dSmrg 	  && wi::leu_p (n_unroll, wi::to_widest (niter)))
8971debfc3dSmrg 	{
8981debfc3dSmrg 	  bitmap_ones (wont_exit);
8991debfc3dSmrg 	  if (wi::eq_p (wi::to_widest (niter), n_unroll)
9001debfc3dSmrg 	      || edge_to_cancel)
9011debfc3dSmrg 	    bitmap_clear_bit (wont_exit, 0);
9021debfc3dSmrg 	}
9031debfc3dSmrg       else
9041debfc3dSmrg 	{
9051debfc3dSmrg 	  exit = NULL;
9061debfc3dSmrg 	  bitmap_clear (wont_exit);
9071debfc3dSmrg 	}
908a2dc1f3fSmrg       if (may_be_zero)
909a2dc1f3fSmrg 	bitmap_clear_bit (wont_exit, 1);
9101debfc3dSmrg 
9111debfc3dSmrg       if (!gimple_duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
9121debfc3dSmrg 						 n_unroll, wont_exit,
9131debfc3dSmrg 						 exit, &edges_to_remove,
9141debfc3dSmrg 						 DLTHE_FLAG_UPDATE_FREQ
9151debfc3dSmrg 						 | DLTHE_FLAG_COMPLETTE_PEEL))
9161debfc3dSmrg 	{
9171debfc3dSmrg           free_original_copy_tables ();
9181debfc3dSmrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
9191debfc3dSmrg 	    fprintf (dump_file, "Failed to duplicate the loop\n");
9201debfc3dSmrg 	  return false;
9211debfc3dSmrg 	}
9221debfc3dSmrg 
9231debfc3dSmrg       free_original_copy_tables ();
9241debfc3dSmrg     }
9251debfc3dSmrg 
9261debfc3dSmrg   /* Remove the conditional from the last copy of the loop.  */
9271debfc3dSmrg   if (edge_to_cancel)
9281debfc3dSmrg     {
9291debfc3dSmrg       gcond *cond = as_a <gcond *> (last_stmt (edge_to_cancel->src));
9301debfc3dSmrg       force_edge_cold (edge_to_cancel, true);
9311debfc3dSmrg       if (edge_to_cancel->flags & EDGE_TRUE_VALUE)
9321debfc3dSmrg 	gimple_cond_make_false (cond);
9331debfc3dSmrg       else
9341debfc3dSmrg 	gimple_cond_make_true (cond);
9351debfc3dSmrg       update_stmt (cond);
936a2dc1f3fSmrg       /* Do not remove the path, as doing so may remove outer loop and
937a2dc1f3fSmrg 	 confuse bookkeeping code in tree_unroll_loops_completely.  */
9381debfc3dSmrg     }
9391debfc3dSmrg 
9401debfc3dSmrg   /* Store the loop for later unlooping and exit removal.  */
9411debfc3dSmrg   loops_to_unloop.safe_push (loop);
9421debfc3dSmrg   loops_to_unloop_nunroll.safe_push (n_unroll);
9431debfc3dSmrg 
9441debfc3dSmrg   if (dump_enabled_p ())
9451debfc3dSmrg     {
9461debfc3dSmrg       if (!n_unroll)
9471debfc3dSmrg         dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, locus,
9481debfc3dSmrg                          "loop turned into non-loop; it never loops\n");
9491debfc3dSmrg       else
9501debfc3dSmrg         {
9511debfc3dSmrg           dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, locus,
9521debfc3dSmrg                            "loop with %d iterations completely unrolled",
953a2dc1f3fSmrg 			   (int) n_unroll);
954a2dc1f3fSmrg           if (loop->header->count.initialized_p ())
9551debfc3dSmrg             dump_printf (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS,
9561debfc3dSmrg                          " (header execution count %d)",
957a2dc1f3fSmrg                          (int)loop->header->count.to_gcov_type ());
9581debfc3dSmrg           dump_printf (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, "\n");
9591debfc3dSmrg         }
9601debfc3dSmrg     }
9611debfc3dSmrg 
9621debfc3dSmrg   if (dump_file && (dump_flags & TDF_DETAILS))
9631debfc3dSmrg     {
9641debfc3dSmrg       if (exit)
9651debfc3dSmrg         fprintf (dump_file, "Exit condition of peeled iterations was "
9661debfc3dSmrg 		 "eliminated.\n");
9671debfc3dSmrg       if (edge_to_cancel)
9681debfc3dSmrg         fprintf (dump_file, "Last iteration exit edge was proved true.\n");
9691debfc3dSmrg       else
9701debfc3dSmrg         fprintf (dump_file, "Latch of last iteration was marked by "
9711debfc3dSmrg 		 "__builtin_unreachable ().\n");
9721debfc3dSmrg     }
9731debfc3dSmrg 
9741debfc3dSmrg   return true;
9751debfc3dSmrg }
9761debfc3dSmrg 
9771debfc3dSmrg /* Return number of instructions after peeling.  */
9781debfc3dSmrg static unsigned HOST_WIDE_INT
estimated_peeled_sequence_size(struct loop_size * size,unsigned HOST_WIDE_INT npeel)9791debfc3dSmrg estimated_peeled_sequence_size (struct loop_size *size,
9801debfc3dSmrg 			        unsigned HOST_WIDE_INT npeel)
9811debfc3dSmrg {
9821debfc3dSmrg   return MAX (npeel * (HOST_WIDE_INT) (size->overall
9831debfc3dSmrg 			     	       - size->eliminated_by_peeling), 1);
9841debfc3dSmrg }
9851debfc3dSmrg 
9861debfc3dSmrg /* If the loop is expected to iterate N times and is
9871debfc3dSmrg    small enough, duplicate the loop body N+1 times before
9881debfc3dSmrg    the loop itself.  This way the hot path will never
9891debfc3dSmrg    enter the loop.
9901debfc3dSmrg    Parameters are the same as for try_unroll_loops_completely */
9911debfc3dSmrg 
9921debfc3dSmrg static bool
try_peel_loop(class loop * loop,edge exit,tree niter,bool may_be_zero,HOST_WIDE_INT maxiter)993*8feb0f0bSmrg try_peel_loop (class loop *loop,
994a2dc1f3fSmrg 	       edge exit, tree niter, bool may_be_zero,
9951debfc3dSmrg 	       HOST_WIDE_INT maxiter)
9961debfc3dSmrg {
9971debfc3dSmrg   HOST_WIDE_INT npeel;
9981debfc3dSmrg   struct loop_size size;
9991debfc3dSmrg   int peeled_size;
10001debfc3dSmrg 
1001a2dc1f3fSmrg   if (!flag_peel_loops
1002*8feb0f0bSmrg       || param_max_peel_times <= 0
10031debfc3dSmrg       || !peeled_loops)
10041debfc3dSmrg     return false;
10051debfc3dSmrg 
10061debfc3dSmrg   if (bitmap_bit_p (peeled_loops, loop->num))
10071debfc3dSmrg     {
10081debfc3dSmrg       if (dump_file)
10091debfc3dSmrg         fprintf (dump_file, "Not peeling: loop is already peeled\n");
10101debfc3dSmrg       return false;
10111debfc3dSmrg     }
10121debfc3dSmrg 
1013a2dc1f3fSmrg   /* We don't peel loops that will be unrolled as this can duplicate a
1014a2dc1f3fSmrg      loop more times than the user requested.  */
1015a2dc1f3fSmrg   if (loop->unroll)
1016a2dc1f3fSmrg     {
1017a2dc1f3fSmrg       if (dump_file)
1018a2dc1f3fSmrg         fprintf (dump_file, "Not peeling: user didn't want it peeled.\n");
1019a2dc1f3fSmrg       return false;
1020a2dc1f3fSmrg     }
1021a2dc1f3fSmrg 
10221debfc3dSmrg   /* Peel only innermost loops.
10231debfc3dSmrg      While the code is perfectly capable of peeling non-innermost loops,
10241debfc3dSmrg      the heuristics would probably need some improvements. */
10251debfc3dSmrg   if (loop->inner)
10261debfc3dSmrg     {
10271debfc3dSmrg       if (dump_file)
10281debfc3dSmrg 	fprintf (dump_file, "Not peeling: outer loop\n");
10291debfc3dSmrg       return false;
10301debfc3dSmrg     }
10311debfc3dSmrg 
10321debfc3dSmrg   if (!optimize_loop_for_speed_p (loop))
10331debfc3dSmrg     {
10341debfc3dSmrg       if (dump_file)
10351debfc3dSmrg 	fprintf (dump_file, "Not peeling: cold loop\n");
10361debfc3dSmrg       return false;
10371debfc3dSmrg     }
10381debfc3dSmrg 
10391debfc3dSmrg   /* Check if there is an estimate on the number of iterations.  */
10401debfc3dSmrg   npeel = estimated_loop_iterations_int (loop);
10411debfc3dSmrg   if (npeel < 0)
10421debfc3dSmrg     npeel = likely_max_loop_iterations_int (loop);
10431debfc3dSmrg   if (npeel < 0)
10441debfc3dSmrg     {
10451debfc3dSmrg       if (dump_file)
10461debfc3dSmrg         fprintf (dump_file, "Not peeling: number of iterations is not "
10471debfc3dSmrg 	         "estimated\n");
10481debfc3dSmrg       return false;
10491debfc3dSmrg     }
10501debfc3dSmrg   if (maxiter >= 0 && maxiter <= npeel)
10511debfc3dSmrg     {
10521debfc3dSmrg       if (dump_file)
10531debfc3dSmrg 	fprintf (dump_file, "Not peeling: upper bound is known so can "
10541debfc3dSmrg 		 "unroll completely\n");
10551debfc3dSmrg       return false;
10561debfc3dSmrg     }
10571debfc3dSmrg 
10581debfc3dSmrg   /* We want to peel estimated number of iterations + 1 (so we never
10591debfc3dSmrg      enter the loop on quick path).  Check against PARAM_MAX_PEEL_TIMES
10601debfc3dSmrg      and be sure to avoid overflows.  */
1061*8feb0f0bSmrg   if (npeel > param_max_peel_times - 1)
10621debfc3dSmrg     {
10631debfc3dSmrg       if (dump_file)
10641debfc3dSmrg 	fprintf (dump_file, "Not peeling: rolls too much "
10651debfc3dSmrg 		 "(%i + 1 > --param max-peel-times)\n", (int) npeel);
10661debfc3dSmrg       return false;
10671debfc3dSmrg     }
10681debfc3dSmrg   npeel++;
10691debfc3dSmrg 
10701debfc3dSmrg   /* Check peeled loops size.  */
10711debfc3dSmrg   tree_estimate_loop_size (loop, exit, NULL, &size,
1072*8feb0f0bSmrg 			   param_max_peeled_insns);
10731debfc3dSmrg   if ((peeled_size = estimated_peeled_sequence_size (&size, (int) npeel))
1074*8feb0f0bSmrg       > param_max_peeled_insns)
10751debfc3dSmrg     {
10761debfc3dSmrg       if (dump_file)
10771debfc3dSmrg 	fprintf (dump_file, "Not peeling: peeled sequence size is too large "
10781debfc3dSmrg 		 "(%i insns > --param max-peel-insns)", peeled_size);
10791debfc3dSmrg       return false;
10801debfc3dSmrg     }
10811debfc3dSmrg 
1082*8feb0f0bSmrg   if (!dbg_cnt (gimple_unroll))
1083*8feb0f0bSmrg     return false;
1084*8feb0f0bSmrg 
10851debfc3dSmrg   /* Duplicate possibly eliminating the exits.  */
10861debfc3dSmrg   initialize_original_copy_tables ();
10871debfc3dSmrg   auto_sbitmap wont_exit (npeel + 1);
10881debfc3dSmrg   if (exit && niter
10891debfc3dSmrg       && TREE_CODE (niter) == INTEGER_CST
10901debfc3dSmrg       && wi::leu_p (npeel, wi::to_widest (niter)))
10911debfc3dSmrg     {
10921debfc3dSmrg       bitmap_ones (wont_exit);
10931debfc3dSmrg       bitmap_clear_bit (wont_exit, 0);
10941debfc3dSmrg     }
10951debfc3dSmrg   else
10961debfc3dSmrg     {
10971debfc3dSmrg       exit = NULL;
10981debfc3dSmrg       bitmap_clear (wont_exit);
10991debfc3dSmrg     }
1100a2dc1f3fSmrg   if (may_be_zero)
1101a2dc1f3fSmrg     bitmap_clear_bit (wont_exit, 1);
11021debfc3dSmrg   if (!gimple_duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
11031debfc3dSmrg 					     npeel, wont_exit,
11041debfc3dSmrg 					     exit, &edges_to_remove,
11051debfc3dSmrg 					     DLTHE_FLAG_UPDATE_FREQ))
11061debfc3dSmrg     {
11071debfc3dSmrg       free_original_copy_tables ();
11081debfc3dSmrg       return false;
11091debfc3dSmrg     }
11101debfc3dSmrg   free_original_copy_tables ();
11111debfc3dSmrg   if (dump_file && (dump_flags & TDF_DETAILS))
11121debfc3dSmrg     {
11131debfc3dSmrg       fprintf (dump_file, "Peeled loop %d, %i times.\n",
11141debfc3dSmrg 	       loop->num, (int) npeel);
11151debfc3dSmrg     }
11161debfc3dSmrg   if (loop->any_estimate)
11171debfc3dSmrg     {
11181debfc3dSmrg       if (wi::ltu_p (npeel, loop->nb_iterations_estimate))
11191debfc3dSmrg         loop->nb_iterations_estimate -= npeel;
11201debfc3dSmrg       else
11211debfc3dSmrg 	loop->nb_iterations_estimate = 0;
11221debfc3dSmrg     }
11231debfc3dSmrg   if (loop->any_upper_bound)
11241debfc3dSmrg     {
11251debfc3dSmrg       if (wi::ltu_p (npeel, loop->nb_iterations_upper_bound))
11261debfc3dSmrg         loop->nb_iterations_upper_bound -= npeel;
11271debfc3dSmrg       else
11281debfc3dSmrg         loop->nb_iterations_upper_bound = 0;
11291debfc3dSmrg     }
11301debfc3dSmrg   if (loop->any_likely_upper_bound)
11311debfc3dSmrg     {
11321debfc3dSmrg       if (wi::ltu_p (npeel, loop->nb_iterations_likely_upper_bound))
11331debfc3dSmrg 	loop->nb_iterations_likely_upper_bound -= npeel;
11341debfc3dSmrg       else
11351debfc3dSmrg 	{
11361debfc3dSmrg 	  loop->any_estimate = true;
11371debfc3dSmrg 	  loop->nb_iterations_estimate = 0;
11381debfc3dSmrg 	  loop->nb_iterations_likely_upper_bound = 0;
11391debfc3dSmrg 	}
11401debfc3dSmrg     }
1141a2dc1f3fSmrg   profile_count entry_count = profile_count::zero ();
11421debfc3dSmrg 
11431debfc3dSmrg   edge e;
11441debfc3dSmrg   edge_iterator ei;
11451debfc3dSmrg   FOR_EACH_EDGE (e, ei, loop->header->preds)
11461debfc3dSmrg     if (e->src != loop->latch)
11471debfc3dSmrg       {
1148a2dc1f3fSmrg 	if (e->src->count.initialized_p ())
1149c0a68be4Smrg 	  entry_count += e->src->count;
11501debfc3dSmrg 	gcc_assert (!flow_bb_inside_loop_p (loop, e->src));
11511debfc3dSmrg       }
1152c0a68be4Smrg   profile_probability p;
1153a2dc1f3fSmrg   p = entry_count.probability_in (loop->header->count);
1154a2dc1f3fSmrg   scale_loop_profile (loop, p, 0);
11551debfc3dSmrg   bitmap_set_bit (peeled_loops, loop->num);
11561debfc3dSmrg   return true;
11571debfc3dSmrg }
11581debfc3dSmrg /* Adds a canonical induction variable to LOOP if suitable.
11591debfc3dSmrg    CREATE_IV is true if we may create a new iv.  UL determines
11601debfc3dSmrg    which loops we are allowed to completely unroll.  If TRY_EVAL is true, we try
11611debfc3dSmrg    to determine the number of iterations of a loop by direct evaluation.
11621debfc3dSmrg    Returns true if cfg is changed.   */
11631debfc3dSmrg 
11641debfc3dSmrg static bool
canonicalize_loop_induction_variables(class loop * loop,bool create_iv,enum unroll_level ul,bool try_eval,bool allow_peel)1165*8feb0f0bSmrg canonicalize_loop_induction_variables (class loop *loop,
11661debfc3dSmrg 				       bool create_iv, enum unroll_level ul,
1167a2dc1f3fSmrg 				       bool try_eval, bool allow_peel)
11681debfc3dSmrg {
11691debfc3dSmrg   edge exit = NULL;
11701debfc3dSmrg   tree niter;
11711debfc3dSmrg   HOST_WIDE_INT maxiter;
11721debfc3dSmrg   bool modified = false;
1173c0a68be4Smrg   dump_user_location_t locus;
1174*8feb0f0bSmrg   class tree_niter_desc niter_desc;
1175a2dc1f3fSmrg   bool may_be_zero = false;
11761debfc3dSmrg 
1177a2dc1f3fSmrg   /* For unrolling allow conditional constant or zero iterations, thus
1178a2dc1f3fSmrg      perform loop-header copying on-the-fly.  */
11791debfc3dSmrg   exit = single_exit (loop);
1180a2dc1f3fSmrg   niter = chrec_dont_know;
1181a2dc1f3fSmrg   if (exit && number_of_iterations_exit (loop, exit, &niter_desc, false))
1182a2dc1f3fSmrg     {
1183a2dc1f3fSmrg       niter = niter_desc.niter;
1184a2dc1f3fSmrg       may_be_zero
1185a2dc1f3fSmrg 	= niter_desc.may_be_zero && !integer_zerop (niter_desc.may_be_zero);
1186a2dc1f3fSmrg     }
11871debfc3dSmrg   if (TREE_CODE (niter) == INTEGER_CST)
1188c0a68be4Smrg     locus = last_stmt (exit->src);
11891debfc3dSmrg   else
11901debfc3dSmrg     {
1191a2dc1f3fSmrg       /* For non-constant niter fold may_be_zero into niter again.  */
1192a2dc1f3fSmrg       if (may_be_zero)
1193a2dc1f3fSmrg 	{
1194a2dc1f3fSmrg 	  if (COMPARISON_CLASS_P (niter_desc.may_be_zero))
1195a2dc1f3fSmrg 	    niter = fold_build3 (COND_EXPR, TREE_TYPE (niter),
1196a2dc1f3fSmrg 				 niter_desc.may_be_zero,
1197a2dc1f3fSmrg 				 build_int_cst (TREE_TYPE (niter), 0), niter);
1198a2dc1f3fSmrg 	  else
1199a2dc1f3fSmrg 	    niter = chrec_dont_know;
1200a2dc1f3fSmrg 	  may_be_zero = false;
1201a2dc1f3fSmrg 	}
1202a2dc1f3fSmrg 
12031debfc3dSmrg       /* If the loop has more than one exit, try checking all of them
12041debfc3dSmrg 	 for # of iterations determinable through scev.  */
12051debfc3dSmrg       if (!exit)
12061debfc3dSmrg 	niter = find_loop_niter (loop, &exit);
12071debfc3dSmrg 
12081debfc3dSmrg       /* Finally if everything else fails, try brute force evaluation.  */
12091debfc3dSmrg       if (try_eval
12101debfc3dSmrg 	  && (chrec_contains_undetermined (niter)
12111debfc3dSmrg 	      || TREE_CODE (niter) != INTEGER_CST))
12121debfc3dSmrg 	niter = find_loop_niter_by_eval (loop, &exit);
12131debfc3dSmrg 
12141debfc3dSmrg       if (exit)
1215c0a68be4Smrg         locus = last_stmt (exit->src);
12161debfc3dSmrg 
12171debfc3dSmrg       if (TREE_CODE (niter) != INTEGER_CST)
12181debfc3dSmrg 	exit = NULL;
12191debfc3dSmrg     }
12201debfc3dSmrg 
12211debfc3dSmrg   /* We work exceptionally hard here to estimate the bound
12221debfc3dSmrg      by find_loop_niter_by_eval.  Be sure to keep it for future.  */
12231debfc3dSmrg   if (niter && TREE_CODE (niter) == INTEGER_CST)
12241debfc3dSmrg     {
1225*8feb0f0bSmrg       vec<edge> exits = get_loop_exit_edges  (loop);
12261debfc3dSmrg       record_niter_bound (loop, wi::to_widest (niter),
1227*8feb0f0bSmrg 			  exit == single_likely_exit (loop, exits), true);
1228*8feb0f0bSmrg       exits.release ();
12291debfc3dSmrg     }
12301debfc3dSmrg 
12311debfc3dSmrg   /* Force re-computation of loop bounds so we can remove redundant exits.  */
12321debfc3dSmrg   maxiter = max_loop_iterations_int (loop);
12331debfc3dSmrg 
12341debfc3dSmrg   if (dump_file && (dump_flags & TDF_DETAILS)
12351debfc3dSmrg       && TREE_CODE (niter) == INTEGER_CST)
12361debfc3dSmrg     {
12371debfc3dSmrg       fprintf (dump_file, "Loop %d iterates ", loop->num);
12381debfc3dSmrg       print_generic_expr (dump_file, niter, TDF_SLIM);
12391debfc3dSmrg       fprintf (dump_file, " times.\n");
12401debfc3dSmrg     }
12411debfc3dSmrg   if (dump_file && (dump_flags & TDF_DETAILS)
12421debfc3dSmrg       && maxiter >= 0)
12431debfc3dSmrg     {
12441debfc3dSmrg       fprintf (dump_file, "Loop %d iterates at most %i times.\n", loop->num,
12451debfc3dSmrg 	       (int)maxiter);
12461debfc3dSmrg     }
12471debfc3dSmrg   if (dump_file && (dump_flags & TDF_DETAILS)
12481debfc3dSmrg       && likely_max_loop_iterations_int (loop) >= 0)
12491debfc3dSmrg     {
12501debfc3dSmrg       fprintf (dump_file, "Loop %d likely iterates at most %i times.\n",
12511debfc3dSmrg 	       loop->num, (int)likely_max_loop_iterations_int (loop));
12521debfc3dSmrg     }
12531debfc3dSmrg 
12541debfc3dSmrg   /* Remove exits that are known to be never taken based on loop bound.
12551debfc3dSmrg      Needs to be called after compilation of max_loop_iterations_int that
12561debfc3dSmrg      populates the loop bounds.  */
12571debfc3dSmrg   modified |= remove_redundant_iv_tests (loop);
12581debfc3dSmrg 
1259a2dc1f3fSmrg   if (try_unroll_loop_completely (loop, exit, niter, may_be_zero, ul,
1260a2dc1f3fSmrg 				  maxiter, locus, allow_peel))
12611debfc3dSmrg     return true;
12621debfc3dSmrg 
12631debfc3dSmrg   if (create_iv
12641debfc3dSmrg       && niter && !chrec_contains_undetermined (niter)
12651debfc3dSmrg       && exit && just_once_each_iteration_p (loop, exit->src))
1266a2dc1f3fSmrg     {
1267a2dc1f3fSmrg       tree iv_niter = niter;
1268a2dc1f3fSmrg       if (may_be_zero)
1269a2dc1f3fSmrg 	{
1270a2dc1f3fSmrg 	  if (COMPARISON_CLASS_P (niter_desc.may_be_zero))
1271a2dc1f3fSmrg 	    iv_niter = fold_build3 (COND_EXPR, TREE_TYPE (iv_niter),
1272a2dc1f3fSmrg 				    niter_desc.may_be_zero,
1273a2dc1f3fSmrg 				    build_int_cst (TREE_TYPE (iv_niter), 0),
1274a2dc1f3fSmrg 				    iv_niter);
1275a2dc1f3fSmrg 	  else
1276a2dc1f3fSmrg 	    iv_niter = NULL_TREE;
1277a2dc1f3fSmrg 	}
1278a2dc1f3fSmrg       if (iv_niter)
1279a2dc1f3fSmrg 	create_canonical_iv (loop, exit, iv_niter);
1280a2dc1f3fSmrg     }
12811debfc3dSmrg 
12821debfc3dSmrg   if (ul == UL_ALL)
1283a2dc1f3fSmrg     modified |= try_peel_loop (loop, exit, niter, may_be_zero, maxiter);
12841debfc3dSmrg 
12851debfc3dSmrg   return modified;
12861debfc3dSmrg }
12871debfc3dSmrg 
12881debfc3dSmrg /* The main entry point of the pass.  Adds canonical induction variables
12891debfc3dSmrg    to the suitable loops.  */
12901debfc3dSmrg 
12911debfc3dSmrg unsigned int
canonicalize_induction_variables(void)12921debfc3dSmrg canonicalize_induction_variables (void)
12931debfc3dSmrg {
1294*8feb0f0bSmrg   class loop *loop;
12951debfc3dSmrg   bool changed = false;
12961debfc3dSmrg   bool irred_invalidated = false;
12971debfc3dSmrg   bitmap loop_closed_ssa_invalidated = BITMAP_ALLOC (NULL);
12981debfc3dSmrg 
1299a2dc1f3fSmrg   estimate_numbers_of_iterations (cfun);
13001debfc3dSmrg 
13011debfc3dSmrg   FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
13021debfc3dSmrg     {
13031debfc3dSmrg       changed |= canonicalize_loop_induction_variables (loop,
13041debfc3dSmrg 							true, UL_SINGLE_ITER,
1305a2dc1f3fSmrg 							true, false);
13061debfc3dSmrg     }
13071debfc3dSmrg   gcc_assert (!need_ssa_update_p (cfun));
13081debfc3dSmrg 
13091debfc3dSmrg   unloop_loops (loop_closed_ssa_invalidated, &irred_invalidated);
13101debfc3dSmrg   if (irred_invalidated
13111debfc3dSmrg       && loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS))
13121debfc3dSmrg     mark_irreducible_loops ();
13131debfc3dSmrg 
13141debfc3dSmrg   /* Clean up the information about numbers of iterations, since brute force
13151debfc3dSmrg      evaluation could reveal new information.  */
1316a2dc1f3fSmrg   free_numbers_of_iterations_estimates (cfun);
13171debfc3dSmrg   scev_reset ();
13181debfc3dSmrg 
13191debfc3dSmrg   if (!bitmap_empty_p (loop_closed_ssa_invalidated))
13201debfc3dSmrg     {
13211debfc3dSmrg       gcc_checking_assert (loops_state_satisfies_p (LOOP_CLOSED_SSA));
13221debfc3dSmrg       rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
13231debfc3dSmrg     }
13241debfc3dSmrg   BITMAP_FREE (loop_closed_ssa_invalidated);
13251debfc3dSmrg 
13261debfc3dSmrg   if (changed)
13271debfc3dSmrg     return TODO_cleanup_cfg;
13281debfc3dSmrg   return 0;
13291debfc3dSmrg }
13301debfc3dSmrg 
13311debfc3dSmrg /* Process loops from innermost to outer, stopping at the innermost
13321debfc3dSmrg    loop we unrolled.  */
13331debfc3dSmrg 
13341debfc3dSmrg static bool
tree_unroll_loops_completely_1(bool may_increase_size,bool unroll_outer,bitmap father_bbs,class loop * loop)13351debfc3dSmrg tree_unroll_loops_completely_1 (bool may_increase_size, bool unroll_outer,
1336*8feb0f0bSmrg 				bitmap father_bbs, class loop *loop)
13371debfc3dSmrg {
1338*8feb0f0bSmrg   class loop *loop_father;
13391debfc3dSmrg   bool changed = false;
1340*8feb0f0bSmrg   class loop *inner;
13411debfc3dSmrg   enum unroll_level ul;
1342a2dc1f3fSmrg   unsigned num = number_of_loops (cfun);
13431debfc3dSmrg 
1344a2dc1f3fSmrg   /* Process inner loops first.  Don't walk loops added by the recursive
1345a2dc1f3fSmrg      calls because SSA form is not up-to-date.  They can be handled in the
1346a2dc1f3fSmrg      next iteration.  */
1347c0a68be4Smrg   bitmap child_father_bbs = NULL;
13481debfc3dSmrg   for (inner = loop->inner; inner != NULL; inner = inner->next)
1349a2dc1f3fSmrg     if ((unsigned) inner->num < num)
1350c0a68be4Smrg       {
1351c0a68be4Smrg 	if (!child_father_bbs)
1352c0a68be4Smrg 	  child_father_bbs = BITMAP_ALLOC (NULL);
1353c0a68be4Smrg 	if (tree_unroll_loops_completely_1 (may_increase_size, unroll_outer,
1354c0a68be4Smrg 					    child_father_bbs, inner))
1355c0a68be4Smrg 	  {
1356c0a68be4Smrg 	    bitmap_ior_into (father_bbs, child_father_bbs);
1357c0a68be4Smrg 	    bitmap_clear (child_father_bbs);
1358c0a68be4Smrg 	    changed = true;
1359c0a68be4Smrg 	  }
1360c0a68be4Smrg       }
1361c0a68be4Smrg   if (child_father_bbs)
1362c0a68be4Smrg     BITMAP_FREE (child_father_bbs);
13631debfc3dSmrg 
13641debfc3dSmrg   /* If we changed an inner loop we cannot process outer loops in this
13651debfc3dSmrg      iteration because SSA form is not up-to-date.  Continue with
13661debfc3dSmrg      siblings of outer loops instead.  */
13671debfc3dSmrg   if (changed)
1368c0a68be4Smrg     {
1369c0a68be4Smrg       /* If we are recorded as father clear all other fathers that
1370c0a68be4Smrg          are necessarily covered already to avoid redundant work.  */
1371c0a68be4Smrg       if (bitmap_bit_p (father_bbs, loop->header->index))
1372c0a68be4Smrg 	{
1373c0a68be4Smrg 	  bitmap_clear (father_bbs);
1374c0a68be4Smrg 	  bitmap_set_bit (father_bbs, loop->header->index);
1375c0a68be4Smrg 	}
13761debfc3dSmrg       return true;
1377c0a68be4Smrg     }
13781debfc3dSmrg 
13791debfc3dSmrg   /* Don't unroll #pragma omp simd loops until the vectorizer
13801debfc3dSmrg      attempts to vectorize those.  */
13811debfc3dSmrg   if (loop->force_vectorize)
13821debfc3dSmrg     return false;
13831debfc3dSmrg 
13841debfc3dSmrg   /* Try to unroll this loop.  */
13851debfc3dSmrg   loop_father = loop_outer (loop);
13861debfc3dSmrg   if (!loop_father)
13871debfc3dSmrg     return false;
13881debfc3dSmrg 
1389a2dc1f3fSmrg   if (loop->unroll > 1)
1390a2dc1f3fSmrg     ul = UL_ALL;
1391a2dc1f3fSmrg   else if (may_increase_size && optimize_loop_nest_for_speed_p (loop)
13921debfc3dSmrg       /* Unroll outermost loops only if asked to do so or they do
13931debfc3dSmrg 	 not cause code growth.  */
13941debfc3dSmrg       && (unroll_outer || loop_outer (loop_father)))
13951debfc3dSmrg     ul = UL_ALL;
13961debfc3dSmrg   else
13971debfc3dSmrg     ul = UL_NO_GROWTH;
13981debfc3dSmrg 
13991debfc3dSmrg   if (canonicalize_loop_induction_variables
1400a2dc1f3fSmrg         (loop, false, ul, !flag_tree_loop_ivcanon, unroll_outer))
14011debfc3dSmrg     {
14021debfc3dSmrg       /* If we'll continue unrolling, we need to propagate constants
14031debfc3dSmrg 	 within the new basic blocks to fold away induction variable
14041debfc3dSmrg 	 computations; otherwise, the size might blow up before the
14051debfc3dSmrg 	 iteration is complete and the IR eventually cleaned up.  */
14061debfc3dSmrg       if (loop_outer (loop_father))
1407c0a68be4Smrg 	{
1408c0a68be4Smrg 	  /* Once we process our father we will have processed
1409c0a68be4Smrg 	     the fathers of our children as well, so avoid doing
1410c0a68be4Smrg 	     redundant work and clear fathers we've gathered sofar.  */
1411c0a68be4Smrg 	  bitmap_clear (father_bbs);
14121debfc3dSmrg 	  bitmap_set_bit (father_bbs, loop_father->header->index);
1413c0a68be4Smrg 	}
14141debfc3dSmrg 
14151debfc3dSmrg       return true;
14161debfc3dSmrg     }
14171debfc3dSmrg 
14181debfc3dSmrg   return false;
14191debfc3dSmrg }
14201debfc3dSmrg 
14211debfc3dSmrg /* Unroll LOOPS completely if they iterate just few times.  Unless
14221debfc3dSmrg    MAY_INCREASE_SIZE is true, perform the unrolling only if the
14231debfc3dSmrg    size of the code does not increase.  */
14241debfc3dSmrg 
1425a2dc1f3fSmrg static unsigned int
tree_unroll_loops_completely(bool may_increase_size,bool unroll_outer)14261debfc3dSmrg tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer)
14271debfc3dSmrg {
14281debfc3dSmrg   bitmap father_bbs = BITMAP_ALLOC (NULL);
14291debfc3dSmrg   bool changed;
14301debfc3dSmrg   int iteration = 0;
14311debfc3dSmrg   bool irred_invalidated = false;
14321debfc3dSmrg 
1433a2dc1f3fSmrg   estimate_numbers_of_iterations (cfun);
1434a2dc1f3fSmrg 
14351debfc3dSmrg   do
14361debfc3dSmrg     {
14371debfc3dSmrg       changed = false;
14381debfc3dSmrg       bitmap loop_closed_ssa_invalidated = NULL;
14391debfc3dSmrg 
14401debfc3dSmrg       if (loops_state_satisfies_p (LOOP_CLOSED_SSA))
14411debfc3dSmrg 	loop_closed_ssa_invalidated = BITMAP_ALLOC (NULL);
14421debfc3dSmrg 
14431debfc3dSmrg       free_numbers_of_iterations_estimates (cfun);
1444a2dc1f3fSmrg       estimate_numbers_of_iterations (cfun);
14451debfc3dSmrg 
14461debfc3dSmrg       changed = tree_unroll_loops_completely_1 (may_increase_size,
14471debfc3dSmrg 						unroll_outer, father_bbs,
14481debfc3dSmrg 						current_loops->tree_root);
14491debfc3dSmrg       if (changed)
14501debfc3dSmrg 	{
14511debfc3dSmrg 	  unsigned i;
14521debfc3dSmrg 
14531debfc3dSmrg           unloop_loops (loop_closed_ssa_invalidated, &irred_invalidated);
14541debfc3dSmrg 
14551debfc3dSmrg 	  /* We cannot use TODO_update_ssa_no_phi because VOPS gets confused.  */
14561debfc3dSmrg 	  if (loop_closed_ssa_invalidated
14571debfc3dSmrg 	      && !bitmap_empty_p (loop_closed_ssa_invalidated))
14581debfc3dSmrg             rewrite_into_loop_closed_ssa (loop_closed_ssa_invalidated,
14591debfc3dSmrg 					  TODO_update_ssa);
14601debfc3dSmrg 	  else
14611debfc3dSmrg 	    update_ssa (TODO_update_ssa);
14621debfc3dSmrg 
14631debfc3dSmrg 	  /* father_bbs is a bitmap of loop father header BB indices.
14641debfc3dSmrg 	     Translate that to what non-root loops these BBs belong to now.  */
14651debfc3dSmrg 	  bitmap_iterator bi;
14661debfc3dSmrg 	  bitmap fathers = BITMAP_ALLOC (NULL);
14671debfc3dSmrg 	  EXECUTE_IF_SET_IN_BITMAP (father_bbs, 0, i, bi)
14681debfc3dSmrg 	    {
14691debfc3dSmrg 	      basic_block unrolled_loop_bb = BASIC_BLOCK_FOR_FN (cfun, i);
14701debfc3dSmrg 	      if (! unrolled_loop_bb)
14711debfc3dSmrg 		continue;
14721debfc3dSmrg 	      if (loop_outer (unrolled_loop_bb->loop_father))
14731debfc3dSmrg 		bitmap_set_bit (fathers,
14741debfc3dSmrg 				unrolled_loop_bb->loop_father->num);
14751debfc3dSmrg 	    }
14761debfc3dSmrg 	  bitmap_clear (father_bbs);
14771debfc3dSmrg 	  /* Propagate the constants within the new basic blocks.  */
14781debfc3dSmrg 	  EXECUTE_IF_SET_IN_BITMAP (fathers, 0, i, bi)
14791debfc3dSmrg 	    {
14801debfc3dSmrg 	      loop_p father = get_loop (cfun, i);
1481c0a68be4Smrg 	      bitmap exit_bbs = BITMAP_ALLOC (NULL);
1482c0a68be4Smrg 	      loop_exit *exit = father->exits->next;
1483c0a68be4Smrg 	      while (exit->e)
1484c0a68be4Smrg 		{
1485c0a68be4Smrg 		  bitmap_set_bit (exit_bbs, exit->e->dest->index);
1486c0a68be4Smrg 		  exit = exit->next;
1487c0a68be4Smrg 		}
1488c0a68be4Smrg 	      do_rpo_vn (cfun, loop_preheader_edge (father), exit_bbs);
14891debfc3dSmrg 	    }
14901debfc3dSmrg 	  BITMAP_FREE (fathers);
14911debfc3dSmrg 
14921debfc3dSmrg 	  /* This will take care of removing completely unrolled loops
14931debfc3dSmrg 	     from the loop structures so we can continue unrolling now
14941debfc3dSmrg 	     innermost loops.  */
14951debfc3dSmrg 	  if (cleanup_tree_cfg ())
14961debfc3dSmrg 	    update_ssa (TODO_update_ssa_only_virtuals);
14971debfc3dSmrg 
14981debfc3dSmrg 	  /* Clean up the information about numbers of iterations, since
14991debfc3dSmrg 	     complete unrolling might have invalidated it.  */
15001debfc3dSmrg 	  scev_reset ();
15011debfc3dSmrg 	  if (flag_checking && loops_state_satisfies_p (LOOP_CLOSED_SSA))
15021debfc3dSmrg 	    verify_loop_closed_ssa (true);
15031debfc3dSmrg 	}
15041debfc3dSmrg       if (loop_closed_ssa_invalidated)
15051debfc3dSmrg         BITMAP_FREE (loop_closed_ssa_invalidated);
15061debfc3dSmrg     }
15071debfc3dSmrg   while (changed
1508*8feb0f0bSmrg 	 && ++iteration <= param_max_unroll_iterations);
15091debfc3dSmrg 
15101debfc3dSmrg   BITMAP_FREE (father_bbs);
15111debfc3dSmrg 
15121debfc3dSmrg   if (irred_invalidated
15131debfc3dSmrg       && loops_state_satisfies_p (LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS))
15141debfc3dSmrg     mark_irreducible_loops ();
15151debfc3dSmrg 
15161debfc3dSmrg   return 0;
15171debfc3dSmrg }
15181debfc3dSmrg 
15191debfc3dSmrg /* Canonical induction variable creation pass.  */
15201debfc3dSmrg 
15211debfc3dSmrg namespace {
15221debfc3dSmrg 
15231debfc3dSmrg const pass_data pass_data_iv_canon =
15241debfc3dSmrg {
15251debfc3dSmrg   GIMPLE_PASS, /* type */
15261debfc3dSmrg   "ivcanon", /* name */
15271debfc3dSmrg   OPTGROUP_LOOP, /* optinfo_flags */
15281debfc3dSmrg   TV_TREE_LOOP_IVCANON, /* tv_id */
15291debfc3dSmrg   ( PROP_cfg | PROP_ssa ), /* properties_required */
15301debfc3dSmrg   0, /* properties_provided */
15311debfc3dSmrg   0, /* properties_destroyed */
15321debfc3dSmrg   0, /* todo_flags_start */
15331debfc3dSmrg   0, /* todo_flags_finish */
15341debfc3dSmrg };
15351debfc3dSmrg 
15361debfc3dSmrg class pass_iv_canon : public gimple_opt_pass
15371debfc3dSmrg {
15381debfc3dSmrg public:
pass_iv_canon(gcc::context * ctxt)15391debfc3dSmrg   pass_iv_canon (gcc::context *ctxt)
15401debfc3dSmrg     : gimple_opt_pass (pass_data_iv_canon, ctxt)
15411debfc3dSmrg   {}
15421debfc3dSmrg 
15431debfc3dSmrg   /* opt_pass methods: */
gate(function *)15441debfc3dSmrg   virtual bool gate (function *) { return flag_tree_loop_ivcanon != 0; }
15451debfc3dSmrg   virtual unsigned int execute (function *fun);
15461debfc3dSmrg 
15471debfc3dSmrg }; // class pass_iv_canon
15481debfc3dSmrg 
15491debfc3dSmrg unsigned int
execute(function * fun)15501debfc3dSmrg pass_iv_canon::execute (function *fun)
15511debfc3dSmrg {
15521debfc3dSmrg   if (number_of_loops (fun) <= 1)
15531debfc3dSmrg     return 0;
15541debfc3dSmrg 
15551debfc3dSmrg   return canonicalize_induction_variables ();
15561debfc3dSmrg }
15571debfc3dSmrg 
15581debfc3dSmrg } // anon namespace
15591debfc3dSmrg 
15601debfc3dSmrg gimple_opt_pass *
make_pass_iv_canon(gcc::context * ctxt)15611debfc3dSmrg make_pass_iv_canon (gcc::context *ctxt)
15621debfc3dSmrg {
15631debfc3dSmrg   return new pass_iv_canon (ctxt);
15641debfc3dSmrg }
15651debfc3dSmrg 
15661debfc3dSmrg /* Complete unrolling of loops.  */
15671debfc3dSmrg 
15681debfc3dSmrg namespace {
15691debfc3dSmrg 
15701debfc3dSmrg const pass_data pass_data_complete_unroll =
15711debfc3dSmrg {
15721debfc3dSmrg   GIMPLE_PASS, /* type */
15731debfc3dSmrg   "cunroll", /* name */
15741debfc3dSmrg   OPTGROUP_LOOP, /* optinfo_flags */
15751debfc3dSmrg   TV_COMPLETE_UNROLL, /* tv_id */
15761debfc3dSmrg   ( PROP_cfg | PROP_ssa ), /* properties_required */
15771debfc3dSmrg   0, /* properties_provided */
15781debfc3dSmrg   0, /* properties_destroyed */
15791debfc3dSmrg   0, /* todo_flags_start */
15801debfc3dSmrg   0, /* todo_flags_finish */
15811debfc3dSmrg };
15821debfc3dSmrg 
15831debfc3dSmrg class pass_complete_unroll : public gimple_opt_pass
15841debfc3dSmrg {
15851debfc3dSmrg public:
pass_complete_unroll(gcc::context * ctxt)15861debfc3dSmrg   pass_complete_unroll (gcc::context *ctxt)
15871debfc3dSmrg     : gimple_opt_pass (pass_data_complete_unroll, ctxt)
15881debfc3dSmrg   {}
15891debfc3dSmrg 
15901debfc3dSmrg   /* opt_pass methods: */
15911debfc3dSmrg   virtual unsigned int execute (function *);
15921debfc3dSmrg 
15931debfc3dSmrg }; // class pass_complete_unroll
15941debfc3dSmrg 
15951debfc3dSmrg unsigned int
execute(function * fun)15961debfc3dSmrg pass_complete_unroll::execute (function *fun)
15971debfc3dSmrg {
15981debfc3dSmrg   if (number_of_loops (fun) <= 1)
15991debfc3dSmrg     return 0;
16001debfc3dSmrg 
16011debfc3dSmrg   /* If we ever decide to run loop peeling more than once, we will need to
16021debfc3dSmrg      track loops already peeled in loop structures themselves to avoid
16031debfc3dSmrg      re-peeling the same loop multiple times.  */
16041debfc3dSmrg   if (flag_peel_loops)
16051debfc3dSmrg     peeled_loops = BITMAP_ALLOC (NULL);
1606*8feb0f0bSmrg   unsigned int val = tree_unroll_loops_completely (flag_cunroll_grow_size,
1607*8feb0f0bSmrg 						   true);
16081debfc3dSmrg   if (peeled_loops)
16091debfc3dSmrg     {
16101debfc3dSmrg       BITMAP_FREE (peeled_loops);
16111debfc3dSmrg       peeled_loops = NULL;
16121debfc3dSmrg     }
16131debfc3dSmrg   return val;
16141debfc3dSmrg }
16151debfc3dSmrg 
16161debfc3dSmrg } // anon namespace
16171debfc3dSmrg 
16181debfc3dSmrg gimple_opt_pass *
make_pass_complete_unroll(gcc::context * ctxt)16191debfc3dSmrg make_pass_complete_unroll (gcc::context *ctxt)
16201debfc3dSmrg {
16211debfc3dSmrg   return new pass_complete_unroll (ctxt);
16221debfc3dSmrg }
16231debfc3dSmrg 
16241debfc3dSmrg /* Complete unrolling of inner loops.  */
16251debfc3dSmrg 
16261debfc3dSmrg namespace {
16271debfc3dSmrg 
16281debfc3dSmrg const pass_data pass_data_complete_unrolli =
16291debfc3dSmrg {
16301debfc3dSmrg   GIMPLE_PASS, /* type */
16311debfc3dSmrg   "cunrolli", /* name */
16321debfc3dSmrg   OPTGROUP_LOOP, /* optinfo_flags */
16331debfc3dSmrg   TV_COMPLETE_UNROLL, /* tv_id */
16341debfc3dSmrg   ( PROP_cfg | PROP_ssa ), /* properties_required */
16351debfc3dSmrg   0, /* properties_provided */
16361debfc3dSmrg   0, /* properties_destroyed */
16371debfc3dSmrg   0, /* todo_flags_start */
16381debfc3dSmrg   0, /* todo_flags_finish */
16391debfc3dSmrg };
16401debfc3dSmrg 
16411debfc3dSmrg class pass_complete_unrolli : public gimple_opt_pass
16421debfc3dSmrg {
16431debfc3dSmrg public:
pass_complete_unrolli(gcc::context * ctxt)16441debfc3dSmrg   pass_complete_unrolli (gcc::context *ctxt)
16451debfc3dSmrg     : gimple_opt_pass (pass_data_complete_unrolli, ctxt)
16461debfc3dSmrg   {}
16471debfc3dSmrg 
16481debfc3dSmrg   /* opt_pass methods: */
gate(function *)16491debfc3dSmrg   virtual bool gate (function *) { return optimize >= 2; }
16501debfc3dSmrg   virtual unsigned int execute (function *);
16511debfc3dSmrg 
16521debfc3dSmrg }; // class pass_complete_unrolli
16531debfc3dSmrg 
16541debfc3dSmrg unsigned int
execute(function * fun)16551debfc3dSmrg pass_complete_unrolli::execute (function *fun)
16561debfc3dSmrg {
16571debfc3dSmrg   unsigned ret = 0;
16581debfc3dSmrg 
1659a2dc1f3fSmrg   loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
16601debfc3dSmrg   if (number_of_loops (fun) > 1)
16611debfc3dSmrg     {
16621debfc3dSmrg       scev_initialize ();
16631debfc3dSmrg       ret = tree_unroll_loops_completely (optimize >= 3, false);
16641debfc3dSmrg       scev_finalize ();
16651debfc3dSmrg     }
16661debfc3dSmrg   loop_optimizer_finalize ();
16671debfc3dSmrg 
16681debfc3dSmrg   return ret;
16691debfc3dSmrg }
16701debfc3dSmrg 
16711debfc3dSmrg } // anon namespace
16721debfc3dSmrg 
16731debfc3dSmrg gimple_opt_pass *
make_pass_complete_unrolli(gcc::context * ctxt)16741debfc3dSmrg make_pass_complete_unrolli (gcc::context *ctxt)
16751debfc3dSmrg {
16761debfc3dSmrg   return new pass_complete_unrolli (ctxt);
16771debfc3dSmrg }
16781debfc3dSmrg 
16791debfc3dSmrg 
1680