This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[rtlopt] Loop unrolling decision cleanup


Hello,

the loop unrolling/peeling decision procedures have again became too
complicated for me to like them. This patch reworks them, separates
decision phase from the execution cleanly and makes decisions on all
the different possibilities independent.

Zdenek

Changelog:
	* cfgloop.c (flow_loop_dump, flow_loops_free, flow_loop_exit_edges_find,
	get_loop_body, cancel_loop, verify_loop_structure, add_histogram):
	Use unsigned variables where appropriate.
	* cfgloopanal.c (simple_loop_p, mark_irreducible_loops,
	num_loop_insns, expected_loop_iterations): Ditto.
	* cfgloopmanip.c (record_exit_edges, duplicate_loop_to_header_edge,
	loopify, fix_loop_placement, can_duplicate_loop_p, create_preheaders,
	force_single_succ_latches): Ditto.
	* loop-unswitch.c (may_unswitch_on_p, unswitch_single_loop): Ditto.
	* predict.c (estimate_probability, estimate_loops_at_level): Ditto.
	* profile.c (instrument_loops, compute_loop_histograms): Ditto.
	* loop-unroll.c (unroll_or_peel_loop): Removed.
	(peel_loop_simple, peel_loop_completely, unroll_loop_stupid,
	unroll_loop_constant_iterations, unroll_loop_runtime_iterations,
	unroll_and_peel_loops): Modified.
	(peel_loops_completely, decide_unrolling_and_peeling,
	decide_peel_simple, decide_peel_once_rolling, decide_peel_completely,
	decide_unroll_stupid, decide_unroll_constant_iterations,
	decide_unroll_runtime_iterations): New.
	* cfgloop.h (enum lpt_dec, struct lpt_decision): New.
	(struct loop): Add lpt_decision, simple, desc, has_desc and ninsns
	fields.
	(expected_loop_iterations, duplicate_loop_to_header_edge): Declaration
	changed.
	(UAP_PEEL_COMPLETELY, UAP_PEEL_ONCE_ROLLING): Removed.
 
Index: cfgloop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgloop.c,v
retrieving revision 1.15.4.4
diff -c -3 -p -r1.15.4.4 cfgloop.c
*** cfgloop.c	8 Nov 2002 20:47:10 -0000	1.15.4.4
--- cfgloop.c	9 Nov 2002 17:39:27 -0000
*************** flow_loop_dump (loop, file, loop_dump_au
*** 115,121 ****
  {
    basic_block *bbs;
    edge e;
!   int i;
    struct loop_histogram *histogram = NULL;
  
    if (! loop || ! loop->header)
--- 115,121 ----
  {
    basic_block *bbs;
    edge e;
!   unsigned i;
    struct loop_histogram *histogram = NULL;
  
    if (! loop || ! loop->header)
*************** flow_loops_free (loops)
*** 234,240 ****
  {
    if (loops->parray)
      {
!       int i;
  
        if (! loops->num)
  	abort ();
--- 234,240 ----
  {
    if (loops->parray)
      {
!       unsigned i;
  
        if (! loops->num)
  	abort ();
*************** flow_loop_exit_edges_find (loop)
*** 303,309 ****
  {
    edge e;
    basic_block node, *bbs;
!   int num_exits, i;
  
    loop->exit_edges = NULL;
    loop->num_exits = 0;
--- 303,309 ----
  {
    edge e;
    basic_block node, *bbs;
!   unsigned num_exits, i;
  
    loop->exit_edges = NULL;
    loop->num_exits = 0;
*************** get_loop_body (loop)
*** 1047,1053 ****
       const struct loop *loop;
  {
    basic_block *tovisit, bb;
!   int tv = 0;
  
    if (!loop->num_nodes)
      abort ();
--- 1047,1053 ----
       const struct loop *loop;
  {
    basic_block *tovisit, bb;
!   unsigned tv = 0;
  
    if (!loop->num_nodes)
      abort ();
*************** get_loop_body (loop)
*** 1058,1064 ****
    if (loop->latch == EXIT_BLOCK_PTR)
      {
        /* There may be blocks unreachable from EXIT_BLOCK.  */
!       if (loop->num_nodes != n_basic_blocks + 2)
  	abort ();
        FOR_EACH_BB (bb)
  	tovisit[tv++] = bb;
--- 1058,1064 ----
    if (loop->latch == EXIT_BLOCK_PTR)
      {
        /* There may be blocks unreachable from EXIT_BLOCK.  */
!       if (loop->num_nodes != (unsigned) n_basic_blocks + 2)
  	abort ();
        FOR_EACH_BB (bb)
  	tovisit[tv++] = bb;
*************** cancel_loop (loops, loop)
*** 1135,1141 ****
       struct loop *loop;
  {
    basic_block *bbs;
!   int i;
  
    if (loop->inner)
      abort ();
--- 1135,1141 ----
       struct loop *loop;
  {
    basic_block *bbs;
!   unsigned i;
  
    if (loop->inner)
      abort ();
*************** void
*** 1178,1184 ****
  verify_loop_structure (loops)
       struct loops *loops;
  {
!   int *sizes, i, j;
    sbitmap irreds;
    basic_block *bbs, bb;
    struct loop *loop;
--- 1178,1184 ----
  verify_loop_structure (loops)
       struct loops *loops;
  {
!   unsigned *sizes, i, j;
    sbitmap irreds;
    basic_block *bbs, bb;
    struct loop *loop;
*************** void
*** 1324,1330 ****
  move_histograms_to_loops (loops)
       struct loops *loops;
  {
!   int i;
  
    for (i = 1; i < loops->num; i++)
      {
--- 1324,1330 ----
  move_histograms_to_loops (loops)
       struct loops *loops;
  {
!   unsigned i;
  
    for (i = 1; i < loops->num; i++)
      {
*************** add_histogram (target, histogram, prob)
*** 1368,1374 ****
       struct loop_histogram *histogram;
       int prob;
  {
!   int i;
  
    if (target->steps > histogram->steps)
      {
--- 1368,1374 ----
       struct loop_histogram *histogram;
       int prob;
  {
!   unsigned i;
  
    if (target->steps > histogram->steps)
      {
Index: cfgloop.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/cfgloop.h,v
retrieving revision 1.1.2.3
diff -c -3 -p -r1.1.2.3 cfgloop.h
*** cfgloop.h	8 Nov 2002 20:47:10 -0000	1.1.2.3
--- cfgloop.h	9 Nov 2002 17:39:27 -0000
*************** along with GCC; see the file COPYING.  I
*** 19,24 ****
--- 19,60 ----
  Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  02111-1307, USA.  */
  
+ /* Structure to hold decision about unrolling/peeling.  */
+ enum lpt_dec
+ {
+   LPT_NONE,
+   LPT_PEEL_COMPLETELY,
+   LPT_PEEL_SIMPLE,
+   LPT_UNROLL_CONSTANT,
+   LPT_UNROLL_RUNTIME,
+   LPT_UNROLL_STUPID
+ };
+ 
+ struct lpt_decision
+ {
+   enum lpt_dec decision;
+   unsigned times;
+ };
+ 
+ /* Description of loop for simple loop unrolling.  */
+ struct loop_desc
+ {
+   int postincr;		/* 1 if increment/decrement is done after loop exit condition.  */
+   rtx stride;		/* Value added to VAR in each iteration.  */
+   rtx var;		/* Loop control variable.  */
+   rtx var_alts;		/* List of definitions of its initial value.  */
+   rtx lim;		/* Expression var is compared with.  */
+   rtx lim_alts;		/* List of definitions of its initial value.  */
+   bool const_iter;      /* True if it iterates constant number of times.  */
+   unsigned HOST_WIDE_INT niter;
+ 			/* Number of iterations if it is constant.  */
+   bool may_be_zero;     /* If we cannot determine that the first iteration will pass.  */
+   enum rtx_code cond;	/* Exit condition.  */
+   int neg;		/* Set to 1 if loop ends when condition is satisfied.  */
+   edge out_edge;	/* The exit edge.  */
+   edge in_edge;		/* And the other one.  */
+ };
+ 
  /* Structure to hold information for each natural loop.  */
  struct loop
  {
*************** struct loop
*** 37,42 ****
--- 73,89 ----
    /* Histogram for a loop.  */
    struct loop_histogram *histogram;
  
+   /* For loop unrolling/peeling decision.  */
+   struct lpt_decision lpt_decision;
+ 
+   /* Simple loop description.  */
+   int simple;
+   struct loop_desc desc;
+   int has_desc;
+ 
+   /* Number of loop insns.  */
+   unsigned ninsns;
+ 
    /* Array of edges along the pre-header extended basic block trace.
       The source of the first edge is the root node of pre-header
       extended basic block, if it exists.  */
*************** struct loop
*** 57,63 ****
    sbitmap nodes;
  
    /* Number of blocks contained within the loop.  */
!   int num_nodes;
  
    /* Array of edges that enter the loop.  */
    edge *entry_edges;
--- 104,110 ----
    sbitmap nodes;
  
    /* Number of blocks contained within the loop.  */
!   unsigned num_nodes;
  
    /* Array of edges that enter the loop.  */
    edge *entry_edges;
*************** struct loop
*** 150,156 ****
  /* Histogram of a loop.  */
  struct loop_histogram
  {
!   int steps;
    gcov_type *counts;
    gcov_type more;
  };
--- 197,203 ----
  /* Histogram of a loop.  */
  struct loop_histogram
  {
!   unsigned steps;
    gcov_type *counts;
    gcov_type more;
  };
*************** enum
*** 168,177 ****
  struct loops
  {
    /* Number of natural loops in the function.  */
!   int num;
  
!   /* Maxium nested loop level in the function.  */
!   int levels;
  
    /* Array of natural loop descriptors (scanning this array in reverse order
       will find the inner loops before their enclosing outer loops).  */
--- 215,224 ----
  struct loops
  {
    /* Number of natural loops in the function.  */
!   unsigned num;
  
!   /* Maximum nested loop level in the function.  */
!   unsigned levels;
  
    /* Array of natural loop descriptors (scanning this array in reverse order
       will find the inner loops before their enclosing outer loops).  */
*************** struct loops
*** 206,231 ****
    int state;
  };
  
- /* Description of loop for simple loop unrolling.  */
- struct loop_desc
- {
-   int postincr;		/* 1 if increment/decrement is done after loop exit condition.  */
-   rtx stride;		/* Value added to VAR in each iteration.  */
-   rtx var;		/* Loop control variable.  */
-   rtx var_alts;		/* List of definitions of its initial value.  */
-   rtx lim;		/* Expression var is compared with.  */
-   rtx lim_alts;		/* List of definitions of its initial value.  */
-   bool const_iter;      /* True if it iterates constant number of times.  */
-   unsigned HOST_WIDE_INT niter;
- 			/* Number of iterations if it is constant.  */
-   bool may_be_zero;     /* If we cannot determine that the first iteration will pass.  */
-   enum rtx_code cond;	/* Exit condition.  */
-   int neg;		/* Set to 1 if loop ends when condition is satisfied.  */
-   edge out_edge;	/* The exit edge.  */
-   edge in_edge;		/* And the other one.  */
- };
- 
- 
  /* Flags for loop discovery.  */
  
  #define LOOP_TREE		1	/* Build loop hierarchy tree.  */
--- 253,258 ----
*************** extern bool simple_loop_p		PARAMS ((stru
*** 297,303 ****
  extern rtx count_loop_iterations	PARAMS ((struct loop_desc *, rtx, rtx));
  extern bool just_once_each_iteration_p	PARAMS ((struct loops *,struct loop *,
  						 basic_block));
! extern int expected_loop_iterations	PARAMS ((const struct loop *));
  
  /* Loop manipulation.  */
  extern bool can_duplicate_loop_p	PARAMS ((struct loop *loop));
--- 324,330 ----
  extern rtx count_loop_iterations	PARAMS ((struct loop_desc *, rtx, rtx));
  extern bool just_once_each_iteration_p	PARAMS ((struct loops *,struct loop *,
  						 basic_block));
! extern unsigned expected_loop_iterations PARAMS ((const struct loop *));
  
  /* Loop manipulation.  */
  extern bool can_duplicate_loop_p	PARAMS ((struct loop *loop));
*************** extern bool can_duplicate_loop_p	PARAMS 
*** 307,315 ****
  #define DLTHE_USE_HISTOGRAM_PROB	0
  #define DLTHE_USE_WONT_EXIT		2
  extern int duplicate_loop_to_header_edge PARAMS ((struct loop *, edge,
! 						struct loops *, int,
  						sbitmap, edge, edge *,
! 						int *, int));
  extern struct loop *loopify		PARAMS ((struct loops *, edge,
  						edge, basic_block));
  extern bool remove_path			PARAMS ((struct loops *, edge));
--- 334,342 ----
  #define DLTHE_USE_HISTOGRAM_PROB	0
  #define DLTHE_USE_WONT_EXIT		2
  extern int duplicate_loop_to_header_edge PARAMS ((struct loop *, edge,
! 						struct loops *, unsigned,
  						sbitmap, edge, edge *,
! 						unsigned *, int));
  extern struct loop *loopify		PARAMS ((struct loops *, edge,
  						edge, basic_block));
  extern bool remove_path			PARAMS ((struct loops *, edge));
*************** enum
*** 327,335 ****
  {
    UAP_PEEL = 1,
    UAP_UNROLL = 2,
!   UAP_UNROLL_ALL = 4,
!   UAP_PEEL_COMPLETELY = 8,
!   UAP_PEEL_ONCE_ROLLING = 16
  };
  
  extern void unroll_and_peel_loops	PARAMS ((struct loops *, int));
--- 354,360 ----
  {
    UAP_PEEL = 1,
    UAP_UNROLL = 2,
!   UAP_UNROLL_ALL = 4
  };
  
  extern void unroll_and_peel_loops	PARAMS ((struct loops *, int));
Index: cfgloopanal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/cfgloopanal.c,v
retrieving revision 1.1.4.4
diff -c -3 -p -r1.1.4.4 cfgloopanal.c
*** cfgloopanal.c	8 Nov 2002 20:47:10 -0000	1.1.4.4
--- cfgloopanal.c	9 Nov 2002 17:39:27 -0000
*************** simple_loop_p (loops, loop, desc)
*** 732,738 ****
       struct loop *loop;
       struct loop_desc *desc;
  {
!   int i;
    basic_block *body;
    edge e;
    struct loop_desc act;
--- 732,738 ----
       struct loop *loop;
       struct loop_desc *desc;
  {
!   unsigned i;
    basic_block *body;
    edge e;
    struct loop_desc act;
*************** void
*** 816,822 ****
  mark_irreducible_loops (loops)
       struct loops *loops;
  {
!   int *dfs_in, *closed, *mr, *n_edges, *stack, i;
    edge **edges, e;
    basic_block act;
    int stack_top, tick, depth;
--- 816,823 ----
  mark_irreducible_loops (loops)
       struct loops *loops;
  {
!   int *dfs_in, *closed, *mr, *n_edges, *stack;
!   unsigned i;
    edge **edges, e;
    basic_block act;
    int stack_top, tick, depth;
*************** num_loop_insns (loop)
*** 967,973 ****
       struct loop *loop;
  {
    basic_block *bbs, bb;
!   int i, ninsns = 0;
    rtx insn;
  
    bbs = get_loop_body (loop);
--- 968,974 ----
       struct loop *loop;
  {
    basic_block *bbs, bb;
!   unsigned i, ninsns = 0;
    rtx insn;
  
    bbs = get_loop_body (loop);
*************** num_loop_insns (loop)
*** 986,992 ****
  /* Returns expected number of LOOP iterations.
     Comput upper bound on number of iterations in case they do not fit integer
     to help loop peeling heuristics.  Use exact counts if at all possible.  */
! int
  expected_loop_iterations (loop)
       const struct loop *loop;
  {
--- 987,993 ----
  /* Returns expected number of LOOP iterations.
     Comput upper bound on number of iterations in case they do not fit integer
     to help loop peeling heuristics.  Use exact counts if at all possible.  */
! unsigned
  expected_loop_iterations (loop)
       const struct loop *loop;
  {
Index: cfgloopmanip.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/cfgloopmanip.c,v
retrieving revision 1.1.2.4
diff -c -3 -p -r1.1.2.4 cfgloopmanip.c
*** cfgloopmanip.c	8 Nov 2002 20:47:10 -0000	1.1.2.4
--- cfgloopmanip.c	9 Nov 2002 17:39:28 -0000
*************** static void place_new_loop		PARAMS ((str
*** 54,60 ****
  static void scale_loop_frequencies	PARAMS ((struct loop *, int, int));
  static void scale_bbs_frequencies	PARAMS ((basic_block *, int, int, int));
  static void record_exit_edges		PARAMS ((edge, basic_block *, int,
! 						edge *, int *, int));
  static basic_block create_preheader	PARAMS ((struct loop *, dominance_info,
  						int));
  
--- 54,60 ----
  static void scale_loop_frequencies	PARAMS ((struct loop *, int, int));
  static void scale_bbs_frequencies	PARAMS ((basic_block *, int, int, int));
  static void record_exit_edges		PARAMS ((edge, basic_block *, int,
! 						edge *, unsigned *, int));
  static basic_block create_preheader	PARAMS ((struct loop *, dominance_info,
  						int));
  
*************** loopify (loops, latch_edge, header_edge,
*** 462,468 ****
    basic_block succ_bb = latch_edge->dest;
    basic_block pred_bb = header_edge->src;
    basic_block *dom_bbs, *body;
!   int n_dom_bbs, i, j;
    sbitmap seen;
    struct loop *loop = xcalloc (1, sizeof (struct loop));
    struct loop *outer = succ_bb->loop_father->outer;
--- 462,468 ----
    basic_block succ_bb = latch_edge->dest;
    basic_block pred_bb = header_edge->src;
    basic_block *dom_bbs, *body;
!   unsigned n_dom_bbs, i, j;
    sbitmap seen;
    struct loop *loop = xcalloc (1, sizeof (struct loop));
    struct loop *outer = succ_bb->loop_father->outer;
*************** loopify (loops, latch_edge, header_edge,
*** 519,525 ****
  
    for (i = 0; i < loop->num_nodes; i++)
      {
!       int nldom;
        basic_block *ldom;
  
        nldom = get_dominated_by (loops->cfg.dom, body[i], &ldom);
--- 519,525 ----
  
    for (i = 0; i < loop->num_nodes; i++)
      {
!       unsigned nldom;
        basic_block *ldom;
  
        nldom = get_dominated_by (loops->cfg.dom, body[i], &ldom);
*************** fix_loop_placement (loop)
*** 548,554 ****
       struct loop *loop;
  {
    basic_block *body;
!   int i;
    edge e;
    struct loop *father = loop->pred[0], *act;
  
--- 548,554 ----
       struct loop *loop;
  {
    basic_block *body;
!   unsigned i;
    edge e;
    struct loop *father = loop->pred[0], *act;
  
*************** can_duplicate_loop_p (loop)
*** 835,841 ****
       struct loop *loop;
  {
    basic_block *bbs;
!   int i;
  
    bbs = get_loop_body (loop);
  
--- 835,841 ----
       struct loop *loop;
  {
    basic_block *bbs;
!   unsigned i;
  
    bbs = get_loop_body (loop);
  
*************** record_exit_edges (orig, bbs, nbbs, to_r
*** 873,879 ****
       basic_block *bbs;
       int nbbs;
       edge *to_remove;
!      int *n_to_remove;
       int is_orig;
  {
    sbitmap my_blocks;
--- 873,879 ----
       basic_block *bbs;
       int nbbs;
       edge *to_remove;
!      unsigned *n_to_remove;
       int is_orig;
  {
    sbitmap my_blocks;
*************** duplicate_loop_to_header_edge (loop, e, 
*** 928,950 ****
       struct loop *loop;
       edge e;
       struct loops *loops;
!      int ndupl;
       sbitmap wont_exit;
       edge orig;
       edge *to_remove;
!      int *n_to_remove;
       int flags;
  {
    struct loop *target, *aloop;
    struct loop **orig_loops;
!   int n_orig_loops;
    basic_block header = loop->header, latch = loop->latch;
    basic_block *new_bbs, *bbs, *first_active;
    basic_block new_bb, bb, first_active_latch = NULL;
    edge ae, latch_edge, he;
!   int i, j, n;
    int is_latch = (latch == e->src);
!   int scale_act, *scale_step, scale_main, p, freq_in, freq_le, freq_out_orig, hsteps;
    int prob_pass_thru, prob_pass_wont_exit, prob_pass_main;
    int add_irreducible_flag;
    gcov_type all_counters, iterations;
--- 928,951 ----
       struct loop *loop;
       edge e;
       struct loops *loops;
!      unsigned ndupl;
       sbitmap wont_exit;
       edge orig;
       edge *to_remove;
!      unsigned *n_to_remove;
       int flags;
  {
    struct loop *target, *aloop;
    struct loop **orig_loops;
!   unsigned n_orig_loops;
    basic_block header = loop->header, latch = loop->latch;
    basic_block *new_bbs, *bbs, *first_active;
    basic_block new_bb, bb, first_active_latch = NULL;
    edge ae, latch_edge, he;
!   unsigned i, j, n;
    int is_latch = (latch == e->src);
!   int scale_act, *scale_step, scale_main, p, freq_in, freq_le, freq_out_orig;
!   unsigned hsteps;
    int prob_pass_thru, prob_pass_wont_exit, prob_pass_main;
    int add_irreducible_flag;
    gcov_type all_counters, iterations;
*************** create_preheaders (loops, flags)
*** 1316,1322 ****
       struct loops *loops;
       int flags;
  {
!   int i;
    for (i = 1; i < loops->num; i++)
      create_preheader (loops->parray[i], loops->cfg.dom, flags);
    loops->state |= LOOPS_HAVE_PREHEADERS;
--- 1317,1323 ----
       struct loops *loops;
       int flags;
  {
!   unsigned i;
    for (i = 1; i < loops->num; i++)
      create_preheader (loops->parray[i], loops->cfg.dom, flags);
    loops->state |= LOOPS_HAVE_PREHEADERS;
*************** void
*** 1327,1333 ****
  force_single_succ_latches (loops)
       struct loops *loops;
  {
!   int i;
    struct loop *loop;
    edge e;
  
--- 1328,1334 ----
  force_single_succ_latches (loops)
       struct loops *loops;
  {
!   unsigned i;
    struct loop *loop;
    edge e;
  
Index: loop-unroll.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/loop-unroll.c,v
retrieving revision 1.1.2.10
diff -c -3 -p -r1.1.2.10 loop-unroll.c
*** loop-unroll.c	8 Nov 2002 20:47:11 -0000	1.1.2.10
--- loop-unroll.c	9 Nov 2002 17:39:28 -0000
*************** Software Foundation, 59 Temple Place - S
*** 29,45 ****
  #include "output.h"
  #include "expr.h"
  
! static void unroll_or_peel_loop PARAMS ((struct loops *, struct loop *, int));
! static bool peel_loop_simple PARAMS ((struct loops *, struct loop *, int));
! static bool peel_loop_completely PARAMS ((struct loops *, struct loop *,
! 					  struct loop_desc *));
! static bool unroll_loop_stupid PARAMS ((struct loops *, struct loop *, int));
! static bool unroll_loop_constant_iterations PARAMS ((struct loops *,
! 						     struct loop *,
! 						     int, struct loop_desc *));
! static bool unroll_loop_runtime_iterations PARAMS ((struct loops *,
! 						    struct loop *, int,
! 						    struct loop_desc *));
  
  /* Unroll and peel (depending on FLAGS) LOOPS.  */
  void
--- 29,49 ----
  #include "output.h"
  #include "expr.h"
  
! static void decide_unrolling_and_peeling PARAMS ((struct loops *, int));
! static void peel_loops_completely PARAMS ((struct loops *, int));
! static void decide_peel_simple PARAMS ((struct loops *, struct loop *, int));
! static void decide_peel_once_rolling PARAMS ((struct loops *, struct loop *, int));
! static void decide_peel_completely PARAMS ((struct loops *, struct loop *, int));
! static void decide_unroll_stupid PARAMS ((struct loops *, struct loop *, int));
! static void decide_unroll_constant_iterations PARAMS ((struct loops *, struct loop *, int));
! static void decide_unroll_runtime_iterations PARAMS ((struct loops *, struct loop *, int));
! static void peel_loop_simple PARAMS ((struct loops *, struct loop *));
! static void peel_loop_completely PARAMS ((struct loops *, struct loop *));
! static void unroll_loop_stupid PARAMS ((struct loops *, struct loop *));
! static void unroll_loop_constant_iterations PARAMS ((struct loops *,
! 						     struct loop *));
! static void unroll_loop_runtime_iterations PARAMS ((struct loops *,
! 						    struct loop *));
  
  /* Unroll and peel (depending on FLAGS) LOOPS.  */
  void
*************** unroll_and_peel_loops (loops, flags)
*** 47,54 ****
       struct loops *loops;
       int flags;
  {
!   struct loop *loop = loops->tree_root, *next;
  
    while (loop->inner)
      loop = loop->inner;
  
--- 51,67 ----
       struct loops *loops;
       int flags;
  {
!   struct loop *loop, *next;
!   int check;
! 
!   /* First perform complete loop peeling (it is almost surely a win,
!      and affects parameters for further decision a lot).  */
!   peel_loops_completely (loops, flags);
  
+   /* Now decide rest of unrolling and peeling.  */
+   decide_unrolling_and_peeling (loops, flags);
+ 
+   loop = loops->tree_root;
    while (loop->inner)
      loop = loop->inner;
  
*************** unroll_and_peel_loops (loops, flags)
*** 64,90 ****
        else
  	next = loop->outer;
  
!       unroll_or_peel_loop (loops, loop, flags);
  #ifdef ENABLE_CHECKING
!       verify_dominators (loops->cfg.dom);
!       verify_loop_structure (loops);
  #endif
        loop = next;
      }
  }
  /* Peel NPEEL iterations from LOOP, remove exit edges (and cancel the loop
     completely).  */
! static bool
! peel_loop_completely (loops, loop, desc)
       struct loops *loops;
       struct loop *loop;
-      struct loop_desc *desc;
  {
    sbitmap wont_exit;
    unsigned HOST_WIDE_INT npeel;
    edge e;
!   int n_remove_edges, i;
    edge *remove_edges;
    
    npeel = desc->niter;
  
--- 77,367 ----
        else
  	next = loop->outer;
  
!       check = 1;
!       switch (loop->lpt_decision.decision)
! 	{
! 	case LPT_PEEL_COMPLETELY:
! 	  /* Already done.  */
! 	  abort ();
! 	case LPT_PEEL_SIMPLE:
! 	  peel_loop_simple (loops, loop);
! 	  break;
! 	case LPT_UNROLL_CONSTANT:
! 	  unroll_loop_constant_iterations (loops, loop);
! 	  break;
! 	case LPT_UNROLL_RUNTIME:
! 	  unroll_loop_runtime_iterations (loops, loop);
! 	  break;
! 	case LPT_UNROLL_STUPID:
! 	  unroll_loop_stupid (loops, loop);
! 	  break;
! 	case LPT_NONE:
! 	  check = 0;
! 	  break;
! 	default:
! 	  abort ();
! 	}
!       if (check)
! 	{
  #ifdef ENABLE_CHECKING
! 	  verify_dominators (loops->cfg.dom);
! 	  verify_loop_structure (loops);
  #endif
+ 	}
+       loop = next;
+     }
+ }
+ 
+ /* Check whether to peel loops completely and do so.  */
+ static void
+ peel_loops_completely (loops, flags)
+      struct loops *loops;
+      int flags;
+ {
+   struct loop *loop, *next;
+ 
+   loop = loops->tree_root;
+   while (loop->inner)
+     loop = loop->inner;
+ 
+   while (loop != loops->tree_root)
+     {
+       if (loop->next)
+ 	{
+ 	  next = loop->next;
+ 	  while (next->inner)
+ 	    next = next->inner;
+ 	}
+       else
+ 	next = loop->outer;
+ 
+       loop->lpt_decision.decision = LPT_NONE;
+       loop->has_desc = 0;
+   
+       if (rtl_dump_file)
+ 	fprintf (rtl_dump_file, ";; Considering loop %d for complete peeling\n",
+ 		 loop->num);
+ 
+       /* Do not peel cold areas.  */
+       if (!maybe_hot_bb_p (loop->header))
+ 	{
+ 	  if (rtl_dump_file)
+ 	    fprintf (rtl_dump_file, ";; Not considering loop, cold area\n");
+ 	  loop = next;
+ 	  continue;
+ 	}
+ 
+       /* Can the loop be manipulated?  */
+       if (!can_duplicate_loop_p (loop))
+ 	{
+ 	  if (rtl_dump_file)
+ 	    fprintf (rtl_dump_file,
+ 		     ";; Not considering loop, cannot duplicate\n");
+ 	  loop = next;
+ 	  continue;
+ 	}
+ 
+       loop->ninsns = num_loop_insns (loop);
+       decide_peel_once_rolling (loops, loop, flags);
+       if (loop->lpt_decision.decision == LPT_NONE)
+ 	decide_peel_completely (loops, loop, flags);
+ 
+       if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
+ 	{
+ #ifdef ENABLE_CHECKING
+ 	  peel_loop_completely (loops, loop);
+ 	  verify_dominators (loops->cfg.dom);
+ 	  verify_loop_structure (loops);
+ #endif
+ 	}
+       loop = next;
+     }
+ }
+ 
+ /* Decide whether unroll or peel and how much.  */
+ static void
+ decide_unrolling_and_peeling (loops, flags)
+      struct loops *loops;
+      int flags;
+ {
+   struct loop *loop = loops->tree_root, *next;
+ 
+   while (loop->inner)
+     loop = loop->inner;
+ 
+   /* Scan the loops, inner ones first.  */
+   while (loop != loops->tree_root)
+     {
+       if (loop->next)
+ 	{
+ 	  next = loop->next;
+ 	  while (next->inner)
+ 	    next = next->inner;
+ 	}
+       else
+ 	next = loop->outer;
+ 
+       loop->lpt_decision.decision = LPT_NONE;
+ 
+       if (rtl_dump_file)
+ 	fprintf (rtl_dump_file, ";; Considering loop %d\n", loop->num);
+ 
+       /* Do not peel cold areas.  */
+       if (!maybe_hot_bb_p (loop->header))
+ 	{
+ 	  if (rtl_dump_file)
+ 	    fprintf (rtl_dump_file, ";; Not considering loop, cold area\n");
+ 	  loop = next;
+ 	  continue;
+ 	}
+ 
+       /* Can the loop be manipulated?  */
+       if (!can_duplicate_loop_p (loop))
+ 	{
+ 	  if (rtl_dump_file)
+ 	    fprintf (rtl_dump_file,
+ 		     ";; Not considering loop, cannot duplicate\n");
+ 	  loop = next;
+ 	  continue;
+ 	}
+ 
+       /* Skip non-innermost loops.  */
+       if (loop->inner)
+ 	{
+ 	  if (rtl_dump_file)
+ 	    fprintf (rtl_dump_file, ";; Not considering loop, is not innermost\n");
+ 	  return;
+ 	}
+ 
+       loop->ninsns = num_loop_insns (loop);
+ 
+       /* Try transformations one by one in decreasing order of
+ 	 priority.  */
+ 
+       decide_unroll_constant_iterations (loops, loop, flags);
+       if (loop->lpt_decision.decision == LPT_NONE)
+ 	decide_unroll_runtime_iterations (loops, loop, flags);
+       if (loop->lpt_decision.decision == LPT_NONE)
+ 	decide_unroll_stupid (loops, loop, flags);
+       if (loop->lpt_decision.decision == LPT_NONE)
+ 	decide_peel_simple (loops, loop, flags);
+ 
        loop = next;
      }
  }
+ 
+ /* Decide whether the loop is once rolling and suitable for complete
+    peeling.  */
+ static void
+ decide_peel_once_rolling (loops, loop, flags)
+      struct loops *loops;
+      struct loop *loop;
+      int flags ATTRIBUTE_UNUSED;
+ {
+   if (rtl_dump_file)
+     fprintf (rtl_dump_file, ";; Considering peeling once rolling loop\n");
+ 
+   /* Is the loop small enough?  */
+   if ((unsigned) PARAM_VALUE (PARAM_MAX_ONCE_PEELED_INSNS) < loop->ninsns)
+     {
+       if (rtl_dump_file)
+ 	fprintf (rtl_dump_file, ";; Not considering loop, is too big\n");
+       return;
+     }
+ 
+   /* Check for simple loops.  */
+   loop->simple = simple_loop_p (loops, loop, &loop->desc);
+   loop->has_desc = 1;
+ 
+   /* Check number of iterations.  */
+   if (!loop->simple || !loop->desc.const_iter || loop->desc.niter !=0)
+     {
+       if (rtl_dump_file)
+ 	fprintf (rtl_dump_file, ";; Unable to prove that the loop rolls exactly once\n");
+       return;
+     }
+ 
+   /* Success.  */
+   if (rtl_dump_file)
+     fprintf (rtl_dump_file, ";; Decided to peel exactly once rolling loop\n");
+   loop->lpt_decision.decision = LPT_PEEL_COMPLETELY;
+ }
+ 
+ /* Decide whether the loop is suitable for complete peeling.  */
+ static void
+ decide_peel_completely (loops, loop, flags)
+      struct loops *loops;
+      struct loop *loop;
+      int flags ATTRIBUTE_UNUSED;
+ {
+   unsigned npeel;
+ 
+   if (rtl_dump_file)
+     fprintf (rtl_dump_file, ";; Considering peeling completely\n");
+ 
+   /* Skip non-innermost loops.  */
+   if (loop->inner)
+     {
+       if (rtl_dump_file)
+ 	fprintf (rtl_dump_file, ";; Not considering loop, is not innermost\n");
+       return;
+     }
+ 
+   /* npeel = number of iterations to peel. */
+   npeel = PARAM_VALUE (PARAM_MAX_COMPLETELY_PEELED_INSNS) / loop->ninsns;
+   if (npeel > (unsigned) PARAM_VALUE (PARAM_MAX_COMPLETELY_PEEL_TIMES))
+     npeel = PARAM_VALUE (PARAM_MAX_COMPLETELY_PEEL_TIMES);
+ 
+   /* Is the loop small enough?  */
+   if (!npeel)
+     {
+       if (rtl_dump_file)
+ 	fprintf (rtl_dump_file, ";; Not considering loop, is too big\n");
+       return;
+     }
+ 
+   /* Check for simple loops.  */
+   if (!loop->has_desc)
+     loop->simple = simple_loop_p (loops, loop, &loop->desc);
+ 
+   /* Check number of iterations.  */
+   if (!loop->simple || !loop->desc.const_iter)
+     {
+       if (rtl_dump_file)
+ 	fprintf (rtl_dump_file, ";; Unable to prove that the loop iterates constant times\n");
+       return;
+     }
+ 
+   if (loop->desc.niter > npeel - 1)
+     {
+       if (rtl_dump_file)
+       	{
+ 	  fprintf (rtl_dump_file, ";; Not peeling loop completely, rolls too much (");
+ 	  fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,(HOST_WIDEST_INT) loop->desc.niter);
+ 	  fprintf (rtl_dump_file, "iterations > %d [maximum peelings])\n", npeel);
+ 	}
+       return;
+     }
+ 
+   /* Success.  */
+   if (rtl_dump_file)
+     fprintf (rtl_dump_file, ";; Decided to peel loop completely\n");
+   loop->lpt_decision.decision = LPT_PEEL_COMPLETELY;
+ }
+ 
  /* Peel NPEEL iterations from LOOP, remove exit edges (and cancel the loop
     completely).  */
! static void
! peel_loop_completely (loops, loop)
       struct loops *loops;
       struct loop *loop;
  {
    sbitmap wont_exit;
    unsigned HOST_WIDE_INT npeel;
    edge e;
!   unsigned n_remove_edges, i;
    edge *remove_edges;
+   struct loop_desc *desc = &loop->desc;
    
    npeel = desc->niter;
  
*************** peel_loop_completely (loops, loop, desc)
*** 123,166 ****
  
    if (rtl_dump_file)
      fprintf (rtl_dump_file, ";; Peeled loop completely, %d times\n", (int) npeel);
- 
-   return true;
  }
  
! /* Unroll LOOP with constant number of iterations described by DESC.
!    MAX_UNROLL is maximal number of allowed unrollings.  */
! static bool
! unroll_loop_constant_iterations (loops, loop, max_unroll, desc)
       struct loops *loops;
       struct loop *loop;
!      int max_unroll;
!      struct loop_desc *desc;
  {
!   unsigned HOST_WIDE_INT niter, exit_mod;
!   sbitmap wont_exit;
!   int n_remove_edges, i, n_copies;
!   edge *remove_edges;
!   int best_copies, best_unroll = -1;
  
!   niter = desc->niter;
  
!   if (niter <= (unsigned) max_unroll + 1)
!     abort ();  /* Should not get here.  */
  
!   /* Find good number of unrollings.  */
!   best_copies = 2 * max_unroll + 10;
  
!   i = 2 * max_unroll + 2;
!   if ((unsigned) i - 1 >= niter)
!     i = niter - 2;
  
!   for (; i >= max_unroll; i--)
      {
!       exit_mod = niter % (i + 1);
  
!       if (desc->postincr)
  	n_copies = exit_mod + i + 1;
!       else if (exit_mod != (unsigned) i || desc->may_be_zero)
  	n_copies = exit_mod + i + 2;
        else
  	n_copies = i + 1;
--- 400,473 ----
  
    if (rtl_dump_file)
      fprintf (rtl_dump_file, ";; Peeled loop completely, %d times\n", (int) npeel);
  }
  
! /* Decide whether to unroll loop iterating constant number of times and how much.  */
! static void
! decide_unroll_constant_iterations (loops, loop, flags)
       struct loops *loops;
       struct loop *loop;
!      int flags;
  {
!   unsigned nunroll, best_copies, best_unroll, n_copies, i;
  
!   if (!flags & UAP_UNROLL)
!     {
!       /* We were not asked to, just return back silently.  */
!       return;
!     }
  
!   if (rtl_dump_file)
!     fprintf (rtl_dump_file, ";; Considering unrolling loop with constant number of iterations\n");
! 
!   /* nunroll = total number of copies of the original loop body in
!      unrolled loop (i.e. if it is 2, we have to duplicate loop body once.  */
!   nunroll = PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS) / loop->ninsns;
!   if (nunroll > (unsigned) PARAM_VALUE (PARAM_MAX_UNROLL_TIMES))
!     nunroll = PARAM_VALUE (PARAM_MAX_UNROLL_TIMES);
! 
!   /* Skip big loops.  */
!   if (nunroll <= 1)
!     {
!       if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Not considering loop, is too big\n");
!       return;
!     }
! 
!   /* Check for simple loops.  */
!   if (!loop->has_desc)
!     loop->simple = simple_loop_p (loops, loop, &loop->desc);
! 
!   /* Check number of iterations.  */
!   if (!loop->simple || !loop->desc.const_iter)
!     {
!       if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Unable to prove that the loop iterates constant times\n");
!       return;
!     }
! 
!   /* Check whether the loop rolls enough to consider.  */
!   if (loop->desc.niter < 2 * nunroll)
!     {
!       if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Not unrolling loop, doesn't roll\n");
!       return;
!     }
  
!   /* Success; now compute number of iterations to unroll.  */
!   best_copies = 2 * nunroll + 10;
  
!   i = 2 * nunroll + 2;
!   if ((unsigned) i - 1 >= loop->desc.niter)
!     i = loop->desc.niter - 2;
  
!   for (; i >= nunroll - 1; i--)
      {
!       unsigned exit_mod = loop->desc.niter % (i + 1);
  
!       if (loop->desc.postincr)
  	n_copies = exit_mod + i + 1;
!       else if (exit_mod != (unsigned) i || loop->desc.may_be_zero)
  	n_copies = exit_mod + i + 2;
        else
  	n_copies = i + 1;
*************** unroll_loop_constant_iterations (loops, 
*** 174,181 ****
  
    if (rtl_dump_file)
      fprintf (rtl_dump_file, ";; max_unroll %d (%d copies, initial %d).\n",
! 	     best_unroll, best_copies, max_unroll);
!   max_unroll = best_unroll;
  
    exit_mod = niter % (max_unroll + 1);
  
--- 481,511 ----
  
    if (rtl_dump_file)
      fprintf (rtl_dump_file, ";; max_unroll %d (%d copies, initial %d).\n",
! 	     best_unroll + 1, best_copies, nunroll);
! 
!   loop->lpt_decision.decision = LPT_UNROLL_CONSTANT;
!   loop->lpt_decision.times = best_unroll;
! }
! 
! /* Unroll LOOP with constant number of iterations described by DESC.
!    MAX_UNROLL is maximal number of allowed unrollings.  */
! static void
! unroll_loop_constant_iterations (loops, loop)
!      struct loops *loops;
!      struct loop *loop;
! {
!   unsigned HOST_WIDE_INT niter;
!   unsigned exit_mod;
!   sbitmap wont_exit;
!   unsigned n_remove_edges, i;
!   edge *remove_edges;
!   unsigned max_unroll = loop->lpt_decision.times;
!   struct loop_desc *desc = &loop->desc;
! 
!   niter = desc->niter;
! 
!   if (niter <= (unsigned) max_unroll + 1)
!     abort ();  /* Should not get here.  */
  
    exit_mod = niter % (max_unroll + 1);
  
*************** unroll_loop_constant_iterations (loops, 
*** 261,287 ****
  
    if (rtl_dump_file)
      fprintf (rtl_dump_file, ";; Unrolled loop %d times, constant # of iterations %i insns\n",max_unroll, num_loop_insns (loop));
!   
!   return true;
  }
  
  /* Unroll LOOP for that we are able to count number of iterations in runtime.
     MAX_UNROLL is maximal number of allowed unrollings.  DESC describes the loop.  */
! static bool
! unroll_loop_runtime_iterations (loops, loop, max_unroll, desc)
       struct loops *loops;
       struct loop *loop;
-      int max_unroll;
-      struct loop_desc *desc;
  {
    rtx niter, init_code, branch_code, jump, label;
!   int i, j, p;
    basic_block preheader, *body, *dom_bbs, swtch, ezc_swtch;
!   int n_dom_bbs;
    sbitmap wont_exit;
!   int may_exit_copy, n_peel, n_remove_edges;
    edge *remove_edges, e;
    bool extra_zero_check, last_may_exit;
  
    /* Remember blocks whose dominators will have to be updated.  */
    dom_bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
--- 591,683 ----
  
    if (rtl_dump_file)
      fprintf (rtl_dump_file, ";; Unrolled loop %d times, constant # of iterations %i insns\n",max_unroll, num_loop_insns (loop));
! }
! 
! /* Decide whether to unroll loop iterating runtime computable number of times
!    and how much.  */
! static void
! decide_unroll_runtime_iterations (loops, loop, flags)
!      struct loops *loops;
!      struct loop *loop;
!      int flags;
! {
!   unsigned nunroll, i;
! 
!   if (!flags & UAP_UNROLL)
!     {
!       /* We were not asked to, just return back silently.  */
!       return;
!     }
! 
!   if (rtl_dump_file)
!     fprintf (rtl_dump_file, ";; Considering unrolling loop with runtime computable number of iterations\n");
! 
!   /* nunroll = total number of copies of the original loop body in
!      unrolled loop (i.e. if it is 2, we have to duplicate loop body once.  */
!   nunroll = PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS) / loop->ninsns;
!   if (nunroll > (unsigned) PARAM_VALUE (PARAM_MAX_UNROLL_TIMES))
!     nunroll = PARAM_VALUE (PARAM_MAX_UNROLL_TIMES);
! 
!   /* Skip big loops.  */
!   if (nunroll <= 1)
!     {
!       if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Not considering loop, is too big\n");
!       return;
!     }
! 
!   /* Check for simple loops.  */
!   if (!loop->has_desc)
!     loop->simple = simple_loop_p (loops, loop, &loop->desc);
! 
!   /* Check simpleness.  */
!   if (!loop->simple)
!     {
!       if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Unable to prove that the number of iterations can be counted in runtime\n");
!       return;
!     }
! 
!   if (loop->desc.const_iter)
!     {
!       if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Loop iterates constant times\n");
!       return;
!     }
! 
!   /* If we have profile feedback, check whether the loop rolls.  */
!   if (loop->header->count && expected_loop_iterations (loop) < 2 * nunroll)
!     {
!       if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Not unrolling loop, doesn't roll\n");
!       return;
!     }
! 
!   /* Success; now force nunroll to be power of 2.  */
!   for (i = 1; 2 * i <= nunroll; i *= 2);
! 
!   loop->lpt_decision.decision = LPT_UNROLL_RUNTIME;
!   loop->lpt_decision.times = i - 1;
  }
  
  /* Unroll LOOP for that we are able to count number of iterations in runtime.
     MAX_UNROLL is maximal number of allowed unrollings.  DESC describes the loop.  */
! static void
! unroll_loop_runtime_iterations (loops, loop)
       struct loops *loops;
       struct loop *loop;
  {
    rtx niter, init_code, branch_code, jump, label;
!   unsigned i, j, p;
    basic_block preheader, *body, *dom_bbs, swtch, ezc_swtch;
!   unsigned n_dom_bbs;
    sbitmap wont_exit;
!   int may_exit_copy;
!   unsigned n_peel, n_remove_edges;
    edge *remove_edges, e;
    bool extra_zero_check, last_may_exit;
+   unsigned max_unroll = loop->lpt_decision.times;
+   struct loop_desc *desc = &loop->desc;
  
    /* Remember blocks whose dominators will have to be updated.  */
    dom_bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
*************** unroll_loop_runtime_iterations (loops, l
*** 290,296 ****
    body = get_loop_body (loop);
    for (i = 0; i < loop->num_nodes; i++)
      {
!       int nldom;
        basic_block *ldom;
  
        nldom = get_dominated_by (loops->cfg.dom, body[i], &ldom);
--- 686,692 ----
    body = get_loop_body (loop);
    for (i = 0; i < loop->num_nodes; i++)
      {
!       unsigned nldom;
        basic_block *ldom;
  
        nldom = get_dominated_by (loops->cfg.dom, body[i], &ldom);
*************** unroll_loop_runtime_iterations (loops, l
*** 302,311 ****
      }
    free (body);
  
-   /* Force max_unroll + 1 to be power of 2.  */
-   for (i = 1; 2 * i <= max_unroll + 1; i *= 2);
-   max_unroll = i - 1;
- 
    if (desc->postincr)
      {
        /* Leave exit in first copy.  */
--- 698,703 ----
*************** unroll_loop_runtime_iterations (loops, l
*** 470,800 ****
      fprintf (rtl_dump_file,
  	     ";; Unrolled loop %d times, counting # of iterations in runtime, %i insns\n",
  	     max_unroll, num_loop_insns (loop));
- 
-   return true;
  }
    
! /* Peel a LOOP.  Returs 0 if impossible, 1 otherwise.  */
! static bool
! peel_loop_simple (loops, loop, npeel)
       struct loops *loops;
       struct loop *loop;
!      int npeel;
  {
!   sbitmap wont_exit;
! 
!   wont_exit = sbitmap_alloc (npeel + 1);
!   sbitmap_zero (wont_exit);
  
!   if (!duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
! 		loops, npeel, wont_exit, NULL, NULL, NULL,
! 		DLTHE_FLAG_UPDATE_FREQ | (loop->histogram ? DLTHE_USE_HISTOGRAM_PROB : DLTHE_USE_WONT_EXIT)))
      {
!       if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Peeling unsuccessful\n");
!       return false;
      }
-   
-   free (wont_exit);
  
    if (rtl_dump_file)
!     fprintf (rtl_dump_file, ";; Peeling loop %d times\n", npeel);
  
!   return true;
! }
!   
! /* Unroll a LOOP.  Returs 0 if impossible, 1 otherwise.  */
! static bool
! unroll_loop_stupid (loops, loop, nunroll)
!      struct loops *loops;
!      struct loop *loop;
!      int nunroll;
! {
!   sbitmap wont_exit;
  
!   wont_exit = sbitmap_alloc (nunroll + 1);
!   sbitmap_zero (wont_exit);
  
!   if (!duplicate_loop_to_header_edge (loop, loop_latch_edge (loop),
! 		loops, nunroll, wont_exit, NULL, NULL, NULL,
! 		DLTHE_FLAG_UPDATE_FREQ | DLTHE_USE_WONT_EXIT))
      {
        if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";;  Not unrolling loop, can't duplicate\n");
!       return false;
      }
  
!   free (wont_exit);
!   
    if (loop->histogram)
      {
!       /* We could try to update histogram, but there is no sense as the information
! 	 is not used any more.  */
!       free_histogram (loop->histogram);
!       loop->histogram = NULL;
      }
  
!   if (rtl_dump_file)
!     fprintf (rtl_dump_file, ";; Unrolled loop %d times, %i insns\n",
! 	     nunroll, num_loop_insns (loop));
! 	  
!   return true;
  }
  
! /* Unroll or peel (depending on FLAGS) LOOP.  */
  static void
! unroll_or_peel_loop (loops, loop, flags)
       struct loops *loops;
       struct loop *loop;
-      int flags;
  {
!   int ninsns, i;
!   unsigned HOST_WIDE_INT niter = 0;
!   unsigned nunroll, npeel, npeel_completely, peel_once;
!   struct loop_desc desc;
!   bool simple, exact;
  
    if (rtl_dump_file)
!     fprintf (rtl_dump_file, ";; Considering loop %d\n", loop->num);
  
!   /* Do not unroll/peel cold areas.  */
!   if (!maybe_hot_bb_p (loop->header))
!     {
!       if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Not unrolling/peeling loop, cold area\n");
!       return;
!     }
  
!   /* Can the loop be manipulated?  */
!   if (!can_duplicate_loop_p (loop))
      {
!       if (rtl_dump_file)
! 	fprintf (rtl_dump_file,
! 		 ";; Not unrolling/peeling loop, cannot duplicate\n");
        return;
      }
  
!   /* Count maximal number of unrollings/peelings.  */
!   ninsns = num_loop_insns (loop);
! 
!   /* npeel = number of iterations to peel. */
!   npeel = PARAM_VALUE (PARAM_MAX_PEELED_INSNS) / ninsns;
!   if (npeel > (unsigned) PARAM_VALUE (PARAM_MAX_PEEL_TIMES))
!     npeel = PARAM_VALUE (PARAM_MAX_PEEL_TIMES);
! 
!   npeel_completely = PARAM_VALUE (PARAM_MAX_COMPLETELY_PEELED_INSNS) / ninsns;
!   if (npeel_completely > (unsigned) PARAM_VALUE (PARAM_MAX_COMPLETELY_PEEL_TIMES))
!     npeel_completely = PARAM_VALUE (PARAM_MAX_COMPLETELY_PEEL_TIMES);
! 
!   peel_once = PARAM_VALUE (PARAM_MAX_ONCE_PEELED_INSNS) >= ninsns;
  
    /* nunroll = total number of copies of the original loop body in
       unrolled loop (i.e. if it is 2, we have to duplicate loop body once.  */
!   nunroll = PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS) / ninsns;
    if (nunroll > (unsigned) PARAM_VALUE (PARAM_MAX_UNROLL_TIMES))
      nunroll = PARAM_VALUE (PARAM_MAX_UNROLL_TIMES);
  
    /* Skip big loops.  */
    if (nunroll <= 1)
      {
-       if ((flags & UAP_UNROLL) && rtl_dump_file)
- 	fprintf (rtl_dump_file, ";; Not unrolling loop, is too big\n");
-       flags &= ~(UAP_UNROLL | UAP_UNROLL_ALL);
-     }
- 
-   /* Avoid FAQ - most people when asking for unrolling will expect
-      compiler to remove loop iterating few times.  We handle this as special
-      case of loop peeling but enable it when -funroll-loops is present too.  */
-   if ((flags & (UAP_PEEL | UAP_UNROLL)) && npeel_completely > 0)
-     {
        if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Allowing to peel loop completely\n");
!       flags |= UAP_PEEL_COMPLETELY;
      }
  
!   if (npeel <= 0)
!     {
!       if ((flags & UAP_PEEL) && rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Not peeling loop, is too big\n");
!       flags &= ~UAP_PEEL;
!     }
  
!   if (peel_once)
      {
        if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Allowing to peel once rolling loop\n");
!       flags |= UAP_PEEL_ONCE_ROLLING;
!     }
! 
!   /* Only peel outer loops if they roll just once.  */
!   if (loop->inner)
!     {
!       if ((flags & UAP_PEEL) && rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Not peeling loop, not innermost loop\n");
!       flags &= ~UAP_PEEL & ~UAP_PEEL_COMPLETELY;
!     }
! 
!   /* Shortcut.  */
!   if (!flags)
!     return;
! 
!   /* Check for simple loops.  */
!   simple = simple_loop_p (loops, loop, &desc);
!   if (!simple && !(flags & UAP_UNROLL_ALL))
!     {
!       if ((flags & UAP_UNROLL) && rtl_dump_file)
! 	fprintf (rtl_dump_file, ";;  Not unrolling loop, isn't simple\n");
!       flags &= ~UAP_UNROLL;
!     }
! 
!   /* Try to guess number of iterations.  */
!   exact = false;
!   if (simple)
!     {
!       exact = desc.const_iter;
!       niter = desc.niter;
!  
!       if (!desc.const_iter)
! 	flags &= ~UAP_PEEL_ONCE_ROLLING & ~UAP_PEEL_COMPLETELY;
!       else if (desc.niter > 0)
! 	flags &= ~UAP_PEEL_ONCE_ROLLING;
      }
-   else
-     flags &= ~UAP_PEEL_ONCE_ROLLING & ~UAP_PEEL_COMPLETELY;
  
!   if (!exact)
      {
!       /* Use profile information.  */
!       niter = expected_loop_iterations (loop);
!       if (loop->header->count)
! 	exact = true;
      }
  
!   if (exact)
!     {
!       /* If estimate is good, use it to decide and bound number of peelings.  */
! 
!       /* If we have histogram, use it.  */
!       if (loop->histogram)
! 	{
! 	  gcov_type all_counters, act_counters;
! 	  all_counters = loop->histogram->more;
! 	  for (i = 0; i < loop->histogram->steps; i++)
! 	    all_counters += loop->histogram->counts[i];
! 	  act_counters = 0;
! 	  if (!all_counters)
! 	    {
! 	      if ((flags & UAP_PEEL) && rtl_dump_file)
! 		fprintf (rtl_dump_file, ";; Not peeling loop, never exits\n");
! 	      flags &= ~UAP_PEEL;
! 	    }
! 	  else
! 	    {
! 	      for (i = 0; i < loop->histogram->steps; i++)
! 		{
! 		  if (act_counters * REG_BR_PROB_BASE >= all_counters * PARAM_VALUE (PARAM_HISTOGRAM_PEEL_RATIO))
! 		    break;
! 		  act_counters += loop->histogram->counts[i];
! 		}
! 	      if (act_counters * REG_BR_PROB_BASE < all_counters * PARAM_VALUE (PARAM_HISTOGRAM_PEEL_RATIO))
! 		i = npeel + 1;
! 	      if ((unsigned) i > npeel)
! 		{
! 		  if ((flags & UAP_PEEL) && rtl_dump_file)
! 		    fprintf (rtl_dump_file,
! 		  	     ";; Not peeling loop, rolls too much (%d iterations > %d [maximum peelings])\n",
! 		  	     i, (int) npeel);
! 		  flags &= ~UAP_PEEL;
! 		}
! 	      else
! 		npeel = i;
! 	    }
! 	}
!       else if (niter + 1 > npeel)
! 	{
! 	  if ((flags & UAP_PEEL) && rtl_dump_file)
! 	    {
! 	      fprintf (rtl_dump_file, ";; Not peeling loop, rolls too much (");
! 	      fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) (niter + 1));
! 	      fprintf (rtl_dump_file, " iterations > %d [maximum peelings])\n", npeel);
! 	    }
! 	  flags &= ~UAP_PEEL;
! 	}
!       else
!        	npeel = niter + 1;
! 
!       if (niter + 1 > npeel_completely)
! 	{
! 	  if ((flags & UAP_PEEL_COMPLETELY) && rtl_dump_file)
! 	    {
! 	      fprintf (rtl_dump_file, ";; Not peeling loop completely, rolls too much (");
! 	      fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,(HOST_WIDEST_INT) (niter + 1));
! 	      fprintf (rtl_dump_file, "iterations > %d [maximum peelings])\n", npeel_completely);
! 	    }
! 	  flags &= ~UAP_PEEL_COMPLETELY;
! 	}
! 
!       /* And unrollings.  */
!       if (niter < 2 * nunroll)
! 	{
! 	  if (rtl_dump_file)
! 	    fprintf (rtl_dump_file, ";; Not unrolling loop, doesn't roll\n");
! 	  flags &= ~(UAP_UNROLL | UAP_UNROLL_ALL);
! 	}
!     }
!   else
!     {
!       /* For now we have no good heuristics to decide whether loop peeling
!          will be effective, so disable it.  */
!       if ((flags & UAP_PEEL) && rtl_dump_file)
! 	fprintf (rtl_dump_file,
! 		 ";; Not peeling loop, no evidence it will be profitable\n");
!       flags &= ~UAP_PEEL;
!     }
  
!   /* Shortcut.  */
!   if (!flags)
!     return;
  
!   /* If we still may both unroll and peel, then unroll.  */
!   if ((flags & UAP_UNROLL) && (flags & UAP_PEEL))
!     {
!       if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";;  Not peelling loop, unrolling instead\n");
!       flags &= ~UAP_PEEL;
!     }
  
!   /* Now we have several cases:  */
!   if (flags & UAP_UNROLL)
!     {
!       /* Unrolling:  */
  
!       if (simple)
! 	{
! 	  if (desc.const_iter)
! 	    /* Loops with constant number of iterations.  */
! 	    unroll_loop_constant_iterations (loops, loop, (int) nunroll,
! 					     &desc);
! 	  else
! 	    /* Loops with countable number of iterations.  */
! 	    unroll_loop_runtime_iterations (loops, loop, (int) nunroll,
! 					    &desc);
! 	}
!       else
! 	/* Stupid unrolling.  */
! 	unroll_loop_stupid (loops, loop, (int) nunroll);
!     }
!   else
      {
!       /* Peeling:  */
! 
!       if ((flags & UAP_PEEL_COMPLETELY) || (flags & UAP_PEEL_ONCE_ROLLING))
! 	/* Peel and remove the loop completely.  */
! 	peel_loop_completely (loops, loop, &desc);
!       else
! 	/* Simple loop peeling.  */
! 	peel_loop_simple (loops, loop, (int) npeel);
      }
  
!   return;
  }
--- 862,1081 ----
      fprintf (rtl_dump_file,
  	     ";; Unrolled loop %d times, counting # of iterations in runtime, %i insns\n",
  	     max_unroll, num_loop_insns (loop));
  }
    
! /* Decide whether to simply peel loop and how much.  */
! static void
! decide_peel_simple (loops, loop, flags)
       struct loops *loops;
       struct loop *loop;
!      int flags;
  {
!   unsigned npeel, i;
  
!   if (!flags & UAP_PEEL)
      {
!       /* We were not asked to, just return back silently.  */
!       return;
      }
  
    if (rtl_dump_file)
!     fprintf (rtl_dump_file, ";; Considering simply peeling loop\n");
  
!   /* npeel = number of iterations to peel. */
!   npeel = PARAM_VALUE (PARAM_MAX_PEELED_INSNS) / loop->ninsns;
!   if (npeel > (unsigned) PARAM_VALUE (PARAM_MAX_PEEL_TIMES))
!     npeel = PARAM_VALUE (PARAM_MAX_PEEL_TIMES);
  
!   /* Skip big loops.  */
!   if (!npeel)
!     {
!       if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Not considering loop, is too big\n");
!       return;
!     }
  
!   /* Check for simple loops.  */
!   if (!loop->has_desc)
!     loop->simple = simple_loop_p (loops, loop, &loop->desc);
! 
!   /* Check number of iterations.  */
!   if (loop->simple &&loop->desc.const_iter)
      {
        if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Loop iterates constant times\n");
!       return;
      }
  
!   /* If we have profile feedback, check whether the loop rolls.  */
    if (loop->histogram)
      {
!       gcov_type all_counters, act_counters;
!       all_counters = loop->histogram->more;
!       for (i = 0; i < loop->histogram->steps; i++)
! 	all_counters += loop->histogram->counts[i];
!       act_counters = 0;
!       if (!all_counters)
! 	{
! 	  if (rtl_dump_file)
! 	    fprintf (rtl_dump_file, ";; Not peeling loop, never exits\n");
! 	  return;
! 	}
!       for (i = 0; i < loop->histogram->steps; i++)
! 	{
! 	  if (act_counters * REG_BR_PROB_BASE >= all_counters * PARAM_VALUE (PARAM_HISTOGRAM_PEEL_RATIO))
! 	    break;
! 	  act_counters += loop->histogram->counts[i];
! 	}
!       if (act_counters * REG_BR_PROB_BASE < all_counters * PARAM_VALUE (PARAM_HISTOGRAM_PEEL_RATIO))
! 	i = npeel + 1;
!       if (i > npeel)
! 	{
! 	  if (rtl_dump_file)
! 	    fprintf (rtl_dump_file,
! 		     ";; Not peeling loop, rolls too much (%d iterations > %d [maximum peelings])\n",
! 		     i, (int) npeel);
! 	  return;
! 	}
!       npeel = i;
!     }
!   else if (loop->header->count)
!     {
!       unsigned niter = expected_loop_iterations (loop);
!       if (niter + 1 > npeel)
! 	{
! 	  if (rtl_dump_file)
! 	    {
! 	      fprintf (rtl_dump_file, ";; Not peeling loop, rolls too much (");
! 	      fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) (niter + 1));
! 	      fprintf (rtl_dump_file, " iterations > %d [maximum peelings])\n", npeel);
! 	    }
! 	  return;
! 	}
!       npeel = niter + 1;
!     }
!   else
!     {
!       /* For now we have no good heuristics to decide whether loop peeling
!          will be effective, so disable it.  */
!       if (rtl_dump_file)
! 	fprintf (rtl_dump_file,
! 		 ";; Not peeling loop, no evidence it will be profitable\n");
!       return;
      }
  
!   /* Success.  */
!   loop->lpt_decision.decision = LPT_PEEL_SIMPLE;
!   loop->lpt_decision.times = npeel;
  }
  
! /* Peel a LOOP.  */
  static void
! peel_loop_simple (loops, loop)
       struct loops *loops;
       struct loop *loop;
  {
!   sbitmap wont_exit;
!   unsigned npeel = loop->lpt_decision.times;
! 
!   wont_exit = sbitmap_alloc (npeel + 1);
!   sbitmap_zero (wont_exit);
! 
!   if (!duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
! 		loops, npeel, wont_exit, NULL, NULL, NULL,
! 		DLTHE_FLAG_UPDATE_FREQ | (loop->histogram ? DLTHE_USE_HISTOGRAM_PROB : DLTHE_USE_WONT_EXIT)))
!     abort ();
!   
!   free (wont_exit);
  
    if (rtl_dump_file)
!     fprintf (rtl_dump_file, ";; Peeling loop %d times\n", npeel);
! }
  
! /* Decide whether to unroll loop stupidly and how much.  */
! static void
! decide_unroll_stupid (loops, loop, flags)
!      struct loops *loops;
!      struct loop *loop;
!      int flags;
! {
!   unsigned nunroll;
  
!   if (!flags & UAP_UNROLL_ALL)
      {
!       /* We were not asked to, just return back silently.  */
        return;
      }
  
!   if (rtl_dump_file)
!     fprintf (rtl_dump_file, ";; Considering unrolling loop stupidly\n");
  
    /* nunroll = total number of copies of the original loop body in
       unrolled loop (i.e. if it is 2, we have to duplicate loop body once.  */
!   nunroll = PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS) / loop->ninsns;
    if (nunroll > (unsigned) PARAM_VALUE (PARAM_MAX_UNROLL_TIMES))
      nunroll = PARAM_VALUE (PARAM_MAX_UNROLL_TIMES);
  
    /* Skip big loops.  */
    if (nunroll <= 1)
      {
        if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Not considering loop, is too big\n");
!       return;
      }
  
!   /* Check for simple loops.  */
!   if (!loop->has_desc)
!     loop->simple = simple_loop_p (loops, loop, &loop->desc);
  
!   /* Check simpleness.  */
!   if (loop->simple)
      {
        if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; The loop is simple\n");
!       return;
      }
  
!   /* If we have profile feedback, check whether the loop rolls.  */
!   if (loop->header->count && expected_loop_iterations (loop) < 2 * nunroll)
      {
!       if (rtl_dump_file)
! 	fprintf (rtl_dump_file, ";; Not unrolling loop, doesn't roll\n");
!       return;
      }
  
!   loop->lpt_decision.decision = LPT_UNROLL_STUPID;
!   loop->lpt_decision.times = nunroll - 1;
! }
  
! /* Unroll a LOOP.  */
! static void
! unroll_loop_stupid (loops, loop)
!      struct loops *loops;
!      struct loop *loop;
! {
!   sbitmap wont_exit;
!   unsigned nunroll = loop->lpt_decision.times;
  
!   wont_exit = sbitmap_alloc (nunroll + 1);
!   sbitmap_zero (wont_exit);
  
!   if (!duplicate_loop_to_header_edge (loop, loop_latch_edge (loop),
! 		loops, nunroll, wont_exit, NULL, NULL, NULL,
! 		DLTHE_FLAG_UPDATE_FREQ | DLTHE_USE_WONT_EXIT))
!     abort ();
  
!   free (wont_exit);
!   
!   if (loop->histogram)
      {
!       /* We could try to update histogram, but there is no sense as the information
! 	 is not used any more.  */
!       free_histogram (loop->histogram);
!       loop->histogram = NULL;
      }
  
!   if (rtl_dump_file)
!     fprintf (rtl_dump_file, ";; Unrolled loop %d times, %i insns\n",
! 	     nunroll, num_loop_insns (loop));
  }
Index: loop-unswitch.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/loop-unswitch.c,v
retrieving revision 1.1.2.2
diff -c -3 -p -r1.1.2.2 loop-unswitch.c
*** loop-unswitch.c	8 Nov 2002 20:47:11 -0000	1.1.2.2
--- loop-unswitch.c	9 Nov 2002 17:39:28 -0000
*************** may_unswitch_on_p (loops, bb, loop, body
*** 76,82 ****
       basic_block *body;
  {
    rtx test;
!   int i;
  
    /* It must be a simple conditional jump.  */
    if (!bb->succ || !bb->succ->succ_next || bb->succ->succ_next->succ_next)
--- 76,82 ----
       basic_block *body;
  {
    rtx test;
!   unsigned i;
  
    /* It must be a simple conditional jump.  */
    if (!bb->succ || !bb->succ->succ_next || bb->succ->succ_next->succ_next)
*************** unswitch_single_loop (loops, loop, cond_
*** 134,140 ****
  {
    basic_block *bbs, bb;
    struct loop *nloop;
!   int i, true_first;
    rtx cond, rcond, conds, rconds, acond, split_before;
    int always_true;
    int always_false;
--- 134,141 ----
  {
    basic_block *bbs, bb;
    struct loop *nloop;
!   unsigned i;
!   int true_first;
    rtx cond, rcond, conds, rconds, acond, split_before;
    int always_true;
    int always_false;
Index: predict.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/predict.c,v
retrieving revision 1.73.2.3
diff -c -3 -p -r1.73.2.3 predict.c
*** predict.c	23 Oct 2002 15:48:20 -0000	1.73.2.3
--- predict.c	9 Nov 2002 17:39:28 -0000
*************** estimate_probability (loops_info)
*** 424,430 ****
  {
    dominance_info dominators, post_dominators;
    basic_block bb;
!   int i;
  
    connect_infinite_loops_to_exit ();
    dominators = calculate_dominance_info (CDI_DOMINATORS);
--- 424,430 ----
  {
    dominance_info dominators, post_dominators;
    basic_block bb;
!   unsigned i;
  
    connect_infinite_loops_to_exit ();
    dominators = calculate_dominance_info (CDI_DOMINATORS);
*************** estimate_probability (loops_info)
*** 435,441 ****
    for (i = 1; i < loops_info->num; i++)
      {
        basic_block bb, *bbs;
!       int j;
        int exits;
        struct loop *loop = loops_info->parray[i];
        struct loop_desc desc;
--- 435,441 ----
    for (i = 1; i < loops_info->num; i++)
      {
        basic_block bb, *bbs;
!       unsigned j;
        int exits;
        struct loop *loop = loops_info->parray[i];
        struct loop_desc desc;
*************** estimate_loops_at_level (first_loop)
*** 1069,1075 ****
      {
        edge e;
        basic_block *bbs;
!       int i;
  
        estimate_loops_at_level (loop->inner);
        
--- 1069,1075 ----
      {
        edge e;
        basic_block *bbs;
!       unsigned i;
  
        estimate_loops_at_level (loop->inner);
        
Index: profile.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/profile.c,v
retrieving revision 1.97.2.2
diff -c -3 -p -r1.97.2.2 profile.c
*** profile.c	8 Nov 2002 20:47:12 -0000	1.97.2.2
--- profile.c	9 Nov 2002 17:39:29 -0000
*************** instrument_loops (loops)
*** 219,231 ****
    enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
    rtx *loop_counters;
    rtx sequence;
!   int i, histogram_steps;
    basic_block bb;
    edge e;
    int n_histogram_counters;
    
    histogram_steps = PARAM_VALUE (PARAM_MAX_PEEL_TIMES);
!   if (histogram_steps < PARAM_VALUE (PARAM_MAX_UNROLL_TIMES))
      histogram_steps = PARAM_VALUE (PARAM_MAX_UNROLL_TIMES);
  
    loop_counters = xmalloc (sizeof (rtx) * loops->num);
--- 219,231 ----
    enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
    rtx *loop_counters;
    rtx sequence;
!   unsigned i, histogram_steps;
    basic_block bb;
    edge e;
    int n_histogram_counters;
    
    histogram_steps = PARAM_VALUE (PARAM_MAX_PEEL_TIMES);
!   if (histogram_steps < (unsigned) PARAM_VALUE (PARAM_MAX_UNROLL_TIMES))
      histogram_steps = PARAM_VALUE (PARAM_MAX_UNROLL_TIMES);
  
    loop_counters = xmalloc (sizeof (rtx) * loops->num);
*************** static void
*** 715,726 ****
  compute_loop_histograms (loops)
       struct loops *loops;
  {
!   int histogram_steps;
!   int i;
    gcov_type *histogram_counts, *act_count;
    
    histogram_steps = PARAM_VALUE (PARAM_MAX_PEEL_TIMES);
!   if (histogram_steps < PARAM_VALUE (PARAM_MAX_UNROLL_TIMES))
      histogram_steps = PARAM_VALUE (PARAM_MAX_UNROLL_TIMES);
  
    histogram_counts = get_histogram_counts (loops->num - 1, histogram_steps);
--- 715,726 ----
  compute_loop_histograms (loops)
       struct loops *loops;
  {
!   unsigned histogram_steps;
!   unsigned i;
    gcov_type *histogram_counts, *act_count;
    
    histogram_steps = PARAM_VALUE (PARAM_MAX_PEEL_TIMES);
!   if (histogram_steps < (unsigned) PARAM_VALUE (PARAM_MAX_UNROLL_TIMES))
      histogram_steps = PARAM_VALUE (PARAM_MAX_UNROLL_TIMES);
  
    histogram_counts = get_histogram_counts (loops->num - 1, histogram_steps);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]