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]

[patch] Remove flow_loop_scan


Hello,

at the moment, flow_loop_scan duplicates functionality of other
functions.  Concretely it provides:

LOOP_PRE_HEADER:  gets preheader of the loop (also obtainable as
  loop_preheader_edge (loop)->src) and finds extended preheader
  (i.e. a path of blocks that have only one successor and end in
  preheader) -- unused.

LOOP_ENTRY_EDGES: gets entry edges of loop (there is always only
  one entry edge, obtainable as loop_preheader_edge (loop)).

LOOP_EXIT_EDGES: Gets loop exit edges (can be also obtained from
  get_loop_exit_edges, but often just using loop->single_exit
  is more appropriate).

In addition to being essentially a duplicate code, the values it
stores are not updated by loop manipulation functions, which leads
to a risk of bugs in case someone assumes otherwise.

This patch gets rid of the function, as well as related fields in
loop structures.

The EDGE_LOOP_EXIT --> loop_exit_edge_p transition is due to fact that
flow_loop_exit_edges_find used to mark loop exit edges with EDGE_LOOP_EXIT.

Bootstrapped & regtested on i686, ia64, ppc and x86_64.

Zdenek

	* cfgloop.c (flow_loop_entry_edges_find, flow_loop_exit_edges_find,
	flow_loop_pre_header_scan, flow_loop_pre_header_find,
	flow_loop_scan): Removed.
	(flow_loop_dump): Do not dump removed fields.
	(flow_loop_free): Do not free removed fields.
	(flow_loops_find): Flags argument removed.  Do not call flow_loop_scan.
	(loop_exit_edge_p): New function.
	* cfgloop.h (struct loop): Removed fields pre_header, pre_header_edges,
	num_pre_header_edges, entry_edges, num_entries, exit_edges,
	num_exits, exits_doms.
	(LOOP_TREE, LOOP_PRE_HEADER, LOOP_ENTRY_EDGES, LOOP_EXIT_EDGES,
	LOOP_EDGES, LOOP_ALL): Removed.
	(flow_loop_scan): Declaration removed.
	(loop_exit_edge_p): Declare.
	* cfgloopmanip.c (create_loop_notes): Do not pass flags to
	flow_loops_find.
	* ifcvt.c (mark_loop_exit_edges): Ditto.
	* loop-init.c (flow_loops_find): Ditto.
	* passes.c (rest_of_handle_branch_prob): Ditto.
	* lambda-code.c (perfect_nestify): Do not call flow_loops_find.
	* loop-unroll.c (analyze_insns_in_loop): Do not use
	EDGE_LOOP_EXIT.
	* predict.c (predict_loops): Do not call flow_loop_scan.
	Use get_loop_exit_edges.
	(tree_estimate_probability): Do not pass flags to flow_loops_find.
	* tree-if-conv.c (bb_with_exit_edge_p): Take loop as argument.
	Do not use EDGE_LOOP_EXIT.
	(tree_if_convert_cond_expr, if_convertible_modify_expr_p): Pass loop
	to bb_with_exit_edge_p.
	(if_convertible_loop_p): Do not call flow_loop_scan.  Use
	loop->single_exit.  Do not use EDGE_LOOP_EXIT.  Pass loop
	to bb_with_exit_edge_p.
	(combine_blocks): Pass loop to bb_with_exit_edge_p.  Do not use
	EDGE_LOOP_EXIT.
	* tree-loop-linear.c (linear_transform_loops): Do not call
	flow_loop_scan.  Use loop->single_exit.
	* tree-vect-analyze.c (vect_analyze_operations): Use loop->single_exit.
	(vect_analyze_loop_form): Do not call flow_loop_scan.
	* tree-vect-transform.c (vect_update_ivs_after_vectorizer): Use
	loop->single_exit.
	(vect_do_peeling_for_loop_bound): Use loop_preheader_edge and
	loop->single_exit.
	* tree-vectorizer.c (slpeel_update_phis_for_duplicate_loop,
	slpeel_make_loop_iterate_ntimes, slpeel_can_duplicate_loop_p,
	slpeel_tree_duplicate_loop_to_edge_cfg,
	slpeel_verify_cfg_after_peeling, slpeel_tree_peel_loop_to_edge):
	Use loop_preheader_edge and loop->single_exit.  Do not call
	flow_loop_scan.

Index: cfgloop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgloop.c,v
retrieving revision 1.48
diff -c -3 -p -r1.48 cfgloop.c
*** cfgloop.c	20 Feb 2005 11:09:14 -0000	1.48
--- cfgloop.c	21 Feb 2005 12:07:09 -0000
*************** Software Foundation, 59 Temple Place - S
*** 41,51 ****
  #define LATCH_EDGE(E) (*(int *) (E)->aux)
  
  static void flow_loops_cfg_dump (const struct loops *, FILE *);
- static void flow_loop_entry_edges_find (struct loop *);
- static void flow_loop_exit_edges_find (struct loop *);
  static int flow_loop_nodes_find (basic_block, struct loop *);
- static void flow_loop_pre_header_scan (struct loop *);
- static basic_block flow_loop_pre_header_find (basic_block);
  static int flow_loop_level_compute (struct loop *);
  static void flow_loops_level_compute (struct loops *);
  static void establish_preds (struct loop *);
--- 41,47 ----
*************** flow_loop_dump (const struct loop *loop,
*** 135,161 ****
    fprintf (file, ";;\n;; Loop %d:%s\n", loop->num,
  	     loop->invalid ? " invalid" : "");
  
!   fprintf (file, ";;  header %d, latch %d, pre-header %d\n",
! 	   loop->header->index, loop->latch->index,
! 	   loop->pre_header ? loop->pre_header->index : -1);
    fprintf (file, ";;  depth %d, level %d, outer %ld\n",
  	   loop->depth, loop->level,
  	   (long) (loop->outer ? loop->outer->num : -1));
  
-   if (loop->pre_header_edges)
-     flow_edge_list_print (";;  pre-header edges", loop->pre_header_edges,
- 			  loop->num_pre_header_edges, file);
- 
-   flow_edge_list_print (";;  entry edges", loop->entry_edges,
- 			loop->num_entries, file);
    fprintf (file, ";;  nodes:");
    bbs = get_loop_body (loop);
    for (i = 0; i < loop->num_nodes; i++)
      fprintf (file, " %d", bbs[i]->index);
    free (bbs);
    fprintf (file, "\n");
-   flow_edge_list_print (";;  exit edges", loop->exit_edges,
- 			loop->num_exits, file);
  
    if (loop_dump_aux)
      loop_dump_aux (loop, file, verbose);
--- 131,148 ----
    fprintf (file, ";;\n;; Loop %d:%s\n", loop->num,
  	     loop->invalid ? " invalid" : "");
  
!   fprintf (file, ";;  header %d, latch %d\n",
! 	   loop->header->index, loop->latch->index);
    fprintf (file, ";;  depth %d, level %d, outer %ld\n",
  	   loop->depth, loop->level,
  	   (long) (loop->outer ? loop->outer->num : -1));
  
    fprintf (file, ";;  nodes:");
    bbs = get_loop_body (loop);
    for (i = 0; i < loop->num_nodes; i++)
      fprintf (file, " %d", bbs[i]->index);
    free (bbs);
    fprintf (file, "\n");
  
    if (loop_dump_aux)
      loop_dump_aux (loop, file, verbose);
*************** flow_loops_dump (const struct loops *loo
*** 194,205 ****
  void
  flow_loop_free (struct loop *loop)
  {
-   if (loop->pre_header_edges)
-     free (loop->pre_header_edges);
-   if (loop->entry_edges)
-     free (loop->entry_edges);
-   if (loop->exit_edges)
-     free (loop->exit_edges);
    if (loop->pred)
      free (loop->pred);
    free (loop);
--- 181,186 ----
*************** flow_loops_free (struct loops *loops)
*** 238,332 ****
      }
  }
  
- /* Find the entry edges into the LOOP.  */
- 
- static void
- flow_loop_entry_edges_find (struct loop *loop)
- {
-   edge e;
-   edge_iterator ei;
-   int num_entries;
- 
-   num_entries = 0;
-   FOR_EACH_EDGE (e, ei, loop->header->preds)
-     {
-       if (flow_loop_outside_edge_p (loop, e))
- 	num_entries++;
-     }
- 
-   gcc_assert (num_entries);
- 
-   loop->entry_edges = xmalloc (num_entries * sizeof (edge *));
- 
-   num_entries = 0;
-   FOR_EACH_EDGE (e, ei, loop->header->preds)
-     {
-       if (flow_loop_outside_edge_p (loop, e))
- 	loop->entry_edges[num_entries++] = e;
-     }
- 
-   loop->num_entries = num_entries;
- }
- 
- /* Find the exit edges from the LOOP.  */
- 
- static void
- flow_loop_exit_edges_find (struct loop *loop)
- {
-   edge e;
-   basic_block node, *bbs;
-   unsigned num_exits, i;
- 
-   loop->exit_edges = NULL;
-   loop->num_exits = 0;
- 
-   /* Check all nodes within the loop to see if there are any
-      successors not in the loop.  Note that a node may have multiple
-      exiting edges.  */
-   num_exits = 0;
-   bbs = get_loop_body (loop);
-   for (i = 0; i < loop->num_nodes; i++)
-     {
-       edge_iterator ei;
-       node = bbs[i];
-       FOR_EACH_EDGE (e, ei, node->succs)
- 	{
- 	  basic_block dest = e->dest;
- 
- 	  if (!flow_bb_inside_loop_p (loop, dest))
- 	    num_exits++;
- 	}
-     }
- 
-   if (! num_exits)
-     {
-       free (bbs);
-       return;
-     }
- 
-   loop->exit_edges = xmalloc (num_exits * sizeof (edge *));
- 
-   /* Store all exiting edges into an array.  */
-   num_exits = 0;
-   for (i = 0; i < loop->num_nodes; i++)
-     {
-       edge_iterator ei;
-       node = bbs[i];
-       FOR_EACH_EDGE (e, ei, node->succs)
- 	{
- 	  basic_block dest = e->dest;
- 
- 	  if (!flow_bb_inside_loop_p (loop, dest))
- 	    {
- 	      e->flags |= EDGE_LOOP_EXIT;
- 	      loop->exit_edges[num_exits++] = e;
- 	    }
-       }
-     }
-   free (bbs);
-   loop->num_exits = num_exits;
- }
- 
  /* Find the nodes contained within the LOOP with header HEADER.
     Return the number of nodes within the loop.  */
  
--- 219,224 ----
*************** mark_single_exit_loops (struct loops *lo
*** 434,510 ****
    loops->state |= LOOPS_HAVE_MARKED_SINGLE_EXITS;
  }
  
- /* Find the root node of the loop pre-header extended basic block and
-    the edges along the trace from the root node to the loop header.  */
- 
- static void
- flow_loop_pre_header_scan (struct loop *loop)
- {
-   int num;
-   basic_block ebb;
-   edge e;
- 
-   loop->num_pre_header_edges = 0;
-   if (loop->num_entries != 1)
-     return;
- 
-   ebb = loop->entry_edges[0]->src;
-   if (ebb == ENTRY_BLOCK_PTR)
-     return;
- 
-   /* Count number of edges along trace from loop header to
-      root of pre-header extended basic block.  Usually this is
-      only one or two edges.  */
-   for (num = 1;
-        EDGE_PRED (ebb, 0)->src != ENTRY_BLOCK_PTR && EDGE_COUNT (ebb->preds) == 1;
-        num++)
-     ebb = EDGE_PRED (ebb, 0)->src;
- 
-   loop->pre_header_edges = xmalloc (num * sizeof (edge));
-   loop->num_pre_header_edges = num;
- 
-   /* Store edges in order that they are followed.  The source of the first edge
-      is the root node of the pre-header extended basic block and the
-      destination of the last last edge is the loop header.  */
-   for (e = loop->entry_edges[0]; num; e = EDGE_PRED (e->src, 0))
-     loop->pre_header_edges[--num] = e;
- }
- 
- /* Return the block for the pre-header of the loop with header
-    HEADER.  Return NULL if there is no pre-header.  */
- 
- static basic_block
- flow_loop_pre_header_find (basic_block header)
- {
-   basic_block pre_header;
-   edge e;
-   edge_iterator ei;
- 
-   /* If block p is a predecessor of the header and is the only block
-      that the header does not dominate, then it is the pre-header.  */
-   pre_header = NULL;
-   FOR_EACH_EDGE (e, ei, header->preds)
-     {
-       basic_block node = e->src;
- 
-       if (node != ENTRY_BLOCK_PTR
- 	  && ! dominated_by_p (CDI_DOMINATORS, node, header))
- 	{
- 	  if (pre_header == NULL)
- 	    pre_header = node;
- 	  else
- 	    {
- 	      /* There are multiple edges into the header from outside
- 		 the loop so there is no pre-header block.  */
- 	      pre_header = NULL;
- 	      break;
- 	    }
- 	}
-     }
- 
-   return pre_header;
- }
- 
  static void
  establish_preds (struct loop *loop)
  {
--- 326,331 ----
*************** flow_loops_level_compute (struct loops *
*** 602,640 ****
    flow_loop_level_compute (loops->tree_root);
  }
  
- /* Scan a single natural loop specified by LOOP collecting information
-    about it specified by FLAGS.  */
- 
- int
- flow_loop_scan (struct loop *loop, int flags)
- {
-   if (flags & LOOP_ENTRY_EDGES)
-     {
-       /* Find edges which enter the loop header.
- 	 Note that the entry edges should only
- 	 enter the header of a natural loop.  */
-       flow_loop_entry_edges_find (loop);
-     }
- 
-   if (flags & LOOP_EXIT_EDGES)
-     {
-       /* Find edges which exit the loop.  */
-       flow_loop_exit_edges_find (loop);
-     }
- 
-   if (flags & LOOP_PRE_HEADER)
-     {
-       /* Look to see if the loop has a pre-header node.  */
-       loop->pre_header = flow_loop_pre_header_find (loop->header);
- 
-       /* Find the blocks within the extended basic block of
- 	 the loop pre-header.  */
-       flow_loop_pre_header_scan (loop);
-     }
- 
-   return 1;
- }
- 
  /* A callback to update latch and header info for basic block JUMP created
     by redirecting an edge.  */
  
--- 423,428 ----
*************** initialize_loops_parallel_p (struct loop
*** 800,813 ****
  }
  
  /* Find all the natural loops in the function and save in LOOPS structure and
!    recalculate loop_depth information in basic block structures.  FLAGS
!    controls which loop information is collected.  Return the number of natural
!    loops found.  */
  
  int
! flow_loops_find (struct loops *loops, int flags)
  {
-   int i;
    int b;
    int num_loops;
    edge e;
--- 588,599 ----
  }
  
  /* Find all the natural loops in the function and save in LOOPS structure and
!    recalculate loop_depth information in basic block structures.
!    Return the number of natural loops found.  */
  
  int
! flow_loops_find (struct loops *loops)
  {
    int b;
    int num_loops;
    edge e;
*************** flow_loops_find (struct loops *loops, in
*** 817,827 ****
    basic_block header;
    basic_block bb;
  
-   /* This function cannot be repeatedly called with different
-      flags to build up the loop information.  The loop tree
-      must always be built if this function is called.  */
-   gcc_assert (flags & LOOP_TREE);
- 
    memset (loops, 0, sizeof *loops);
  
    /* We are going to recount the maximum loop depth,
--- 603,608 ----
*************** flow_loops_find (struct loops *loops, in
*** 963,972 ****
  	 loop.  */
        flow_loops_level_compute (loops);
  
-       /* Scan the loops.  */
-       for (i = 1; i < num_loops; i++)
- 	flow_loop_scan (loops->parray[i], flags);
- 
        loops->num = num_loops;
        initialize_loops_parallel_p (loops);
      }
--- 744,749 ----
*************** loop_preheader_edge (const struct loop *
*** 1523,1525 ****
--- 1300,1311 ----
  
    return e;
  }
+ 
+ /* Returns true if E is an exit of LOOP.  */
+ 
+ bool
+ loop_exit_edge_p (const struct loop *loop, edge e)
+ {
+   return (flow_bb_inside_loop_p (loop, e->src)
+ 	  && !flow_bb_inside_loop_p (loop, e->dest));
+ }
Index: cfgloop.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgloop.h,v
retrieving revision 1.40
diff -c -3 -p -r1.40 cfgloop.h
*** cfgloop.h	15 Dec 2004 21:18:42 -0000	1.40
--- cfgloop.h	21 Feb 2005 12:07:09 -0000
*************** struct loop
*** 69,77 ****
    /* Basic block of loop latch.  */
    basic_block latch;
  
-   /* Basic block of loop preheader or NULL if it does not exist.  */
-   basic_block pre_header;
- 
    /* For loop unrolling/peeling decision.  */
    struct lpt_decision lpt_decision;
  
--- 69,74 ----
*************** struct loop
*** 81,94 ****
    /* Average number of executed insns per iteration.  */
    unsigned av_ninsns;
  
-   /* Array of edges along the preheader extended basic block trace.
-      The source of the first edge is the root node of preheader
-      extended basic block, if it exists.  */
-   edge *pre_header_edges;
- 
-   /* Number of edges along the pre_header extended basic block trace.  */
-   int num_pre_header_edges;
- 
    /* The first block in the loop.  This is not necessarily the same as
       the loop header.  */
    basic_block first;
--- 78,83 ----
*************** struct loop
*** 100,120 ****
    /* Number of blocks contained within the loop.  */
    unsigned num_nodes;
  
-   /* Array of edges that enter the loop.  */
-   edge *entry_edges;
- 
-   /* Number of edges that enter the loop.  */
-   int num_entries;
- 
-   /* Array of edges that exit the loop.  */
-   edge *exit_edges;
- 
-   /* Number of edges that exit the loop.  */
-   int num_exits;
- 
-   /* Bitmap of blocks that dominate all exits of the loop.  */
-   sbitmap exits_doms;
- 
    /* The loop nesting depth.  */
    int depth;
  
--- 89,94 ----
*************** struct loops
*** 254,276 ****
  
  extern struct loops *current_loops;
  
- /* Flags for loop discovery.  */
- 
- #define LOOP_TREE		1	/* Build loop hierarchy tree.  */
- #define LOOP_PRE_HEADER		2	/* Analyze loop preheader.  */
- #define LOOP_ENTRY_EDGES	4	/* Find entry edges.  */
- #define LOOP_EXIT_EDGES		8	/* Find exit edges.  */
- #define LOOP_EDGES		(LOOP_ENTRY_EDGES | LOOP_EXIT_EDGES)
- #define LOOP_ALL	       15	/* All of the above  */
- 
  /* Loop recognition.  */
! extern int flow_loops_find (struct loops *, int flags);
  extern void flow_loops_free (struct loops *);
  extern void flow_loops_dump (const struct loops *, FILE *,
  			     void (*)(const struct loop *, FILE *, int), int);
  extern void flow_loop_dump (const struct loop *, FILE *,
  			    void (*)(const struct loop *, FILE *, int), int);
- extern int flow_loop_scan (struct loop *, int);
  extern void flow_loop_free (struct loop *);
  void mark_irreducible_loops (struct loops *);
  void mark_single_exit_loops (struct loops *);
--- 228,240 ----
  
  extern struct loops *current_loops;
  
  /* Loop recognition.  */
! extern int flow_loops_find (struct loops *);
  extern void flow_loops_free (struct loops *);
  extern void flow_loops_dump (const struct loops *, FILE *,
  			     void (*)(const struct loop *, FILE *, int), int);
  extern void flow_loop_dump (const struct loop *, FILE *,
  			    void (*)(const struct loop *, FILE *, int), int);
  extern void flow_loop_free (struct loop *);
  void mark_irreducible_loops (struct loops *);
  void mark_single_exit_loops (struct loops *);
*************** extern unsigned tree_num_loop_insns (str
*** 288,293 ****
--- 252,258 ----
  extern int num_loop_insns (struct loop *);
  extern int average_num_loop_insns (struct loop *);
  extern unsigned get_loop_level (const struct loop *);
+ extern bool loop_exit_edge_p (const struct loop *, edge);
  
  /* Loops & cfg manipulation.  */
  extern basic_block *get_loop_body (const struct loop *);
Index: cfgloopmanip.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgloopmanip.c,v
retrieving revision 1.40
diff -c -3 -p -r1.40 cfgloopmanip.c
*** cfgloopmanip.c	16 Dec 2004 20:01:25 -0000	1.40
--- cfgloopmanip.c	21 Feb 2005 12:07:09 -0000
*************** create_loop_notes (void)
*** 1296,1302 ****
  		NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_BEG);
  #endif
  
!   flow_loops_find (&loops, LOOP_TREE);
    free_dominance_info (CDI_DOMINATORS);
    if (loops.num > 1)
      {
--- 1296,1302 ----
  		NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_BEG);
  #endif
  
!   flow_loops_find (&loops);
    free_dominance_info (CDI_DOMINATORS);
    if (loops.num > 1)
      {
Index: ifcvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ifcvt.c,v
retrieving revision 1.179
diff -c -3 -p -r1.179 ifcvt.c
*** ifcvt.c	25 Jan 2005 23:09:07 -0000	1.179
--- ifcvt.c	21 Feb 2005 12:07:09 -0000
*************** mark_loop_exit_edges (void)
*** 120,126 ****
    basic_block bb;
    edge e;
    
!   flow_loops_find (&loops, LOOP_TREE);
    free_dominance_info (CDI_DOMINATORS);
    
    if (loops.num > 1)
--- 120,126 ----
    basic_block bb;
    edge e;
    
!   flow_loops_find (&loops);
    free_dominance_info (CDI_DOMINATORS);
    
    if (loops.num > 1)
Index: lambda-code.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/lambda-code.c,v
retrieving revision 2.26
diff -c -3 -p -r2.26 lambda-code.c
*** lambda-code.c	17 Feb 2005 16:29:56 -0000	2.26
--- lambda-code.c	21 Feb 2005 12:07:09 -0000
*************** perfect_nestify (struct loops *loops,
*** 2430,2436 ****
  	}
      }
    free (bbs);
-   flow_loops_find (loops, LOOP_ALL);
    return perfect_nest_p (loop);
  }
  
--- 2430,2435 ----
Index: loop-init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop-init.c,v
retrieving revision 1.13
diff -c -3 -p -r1.13 loop-init.c
*** loop-init.c	22 Nov 2004 12:23:53 -0000	1.13
--- loop-init.c	21 Feb 2005 12:07:09 -0000
*************** loop_optimizer_init (FILE *dumpfile)
*** 56,62 ****
  
    /* Find the loops.  */
  
!   if (flow_loops_find (loops, LOOP_TREE) <= 1)
      {
        /* No loops.  */
        flow_loops_free (loops);
--- 56,62 ----
  
    /* Find the loops.  */
  
!   if (flow_loops_find (loops) <= 1)
      {
        /* No loops.  */
        flow_loops_free (loops);
Index: loop-unroll.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop-unroll.c,v
retrieving revision 1.24
diff -c -3 -p -r1.24 loop-unroll.c
*** loop-unroll.c	22 Nov 2004 12:23:53 -0000	1.24
--- loop-unroll.c	21 Feb 2005 12:07:09 -0000
*************** analyze_insns_in_loop (struct loop *loop
*** 1669,1676 ****
      opt_info->loop_preheader = loop_preheader_edge (loop)->src;
    
    if (n_edges == 1
!       && !(edges[0]->flags & EDGE_COMPLEX)
!       && (edges[0]->flags & EDGE_LOOP_EXIT))
      {
        opt_info->loop_exit = loop_split_edge_with (edges[0], NULL_RTX);
        can_apply = true;
--- 1669,1675 ----
      opt_info->loop_preheader = loop_preheader_edge (loop)->src;
    
    if (n_edges == 1
!       && !(edges[0]->flags & EDGE_COMPLEX))
      {
        opt_info->loop_exit = loop_split_edge_with (edges[0], NULL_RTX);
        can_apply = true;
Index: passes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/passes.c,v
retrieving revision 2.71
diff -c -3 -p -r2.71 passes.c
*** passes.c	15 Feb 2005 18:56:44 -0000	2.71
--- passes.c	21 Feb 2005 12:07:09 -0000
*************** rest_of_handle_branch_prob (void)
*** 781,787 ****
  
    /* Discover and record the loop depth at the head of each basic
       block.  The loop infrastructure does the real job for us.  */
!   flow_loops_find (&loops, LOOP_TREE);
  
    if (dump_file)
      flow_loops_dump (&loops, dump_file, NULL, 0);
--- 781,787 ----
  
    /* Discover and record the loop depth at the head of each basic
       block.  The loop infrastructure does the real job for us.  */
!   flow_loops_find (&loops);
  
    if (dump_file)
      flow_loops_dump (&loops, dump_file, NULL, 0);
Index: predict.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/predict.c,v
retrieving revision 1.139
diff -c -3 -p -r1.139 predict.c
*** predict.c	17 Feb 2005 16:19:35 -0000	1.139
--- predict.c	21 Feb 2005 12:07:09 -0000
*************** predict_loops (struct loops *loops_info,
*** 583,595 ****
      {
        basic_block bb, *bbs;
        unsigned j;
!       int exits;
        struct loop *loop = loops_info->parray[i];
        struct niter_desc desc;
        unsigned HOST_WIDE_INT niter;
  
!       flow_loop_scan (loop, LOOP_EXIT_EDGES);
!       exits = loop->num_exits;
  
        if (rtlsimpleloops)
  	{
--- 583,595 ----
      {
        basic_block bb, *bbs;
        unsigned j;
!       unsigned n_exits;
        struct loop *loop = loops_info->parray[i];
        struct niter_desc desc;
        unsigned HOST_WIDE_INT niter;
+       edge *exits;
  
!       exits = get_loop_exit_edges (loop, &n_exits);
  
        if (rtlsimpleloops)
  	{
*************** predict_loops (struct loops *loops_info,
*** 615,625 ****
  	}
        else
  	{
- 	  edge *exits;
- 	  unsigned j, n_exits;
  	  struct tree_niter_desc niter_desc;
  
- 	  exits = get_loop_exit_edges (loop, &n_exits);
  	  for (j = 0; j < n_exits; j++)
  	    {
  	      tree niter = NULL;
--- 615,622 ----
*************** predict_loops (struct loops *loops_info,
*** 647,654 ****
  		}
  	    }
  
- 	  free (exits);
  	}
  
        bbs = get_loop_body (loop);
  
--- 644,651 ----
  		}
  	    }
  
  	}
+       free (exits);
  
        bbs = get_loop_body (loop);
  
*************** predict_loops (struct loops *loops_info,
*** 690,696 ****
  		  (e, PRED_LOOP_EXIT,
  		   (REG_BR_PROB_BASE
  		    - predictor_info [(int) PRED_LOOP_EXIT].hitrate)
! 		   / exits);
  	}
        
        /* Free basic blocks from get_loop_body.  */
--- 687,693 ----
  		  (e, PRED_LOOP_EXIT,
  		   (REG_BR_PROB_BASE
  		    - predictor_info [(int) PRED_LOOP_EXIT].hitrate)
! 		   / n_exits);
  	}
        
        /* Free basic blocks from get_loop_body.  */
*************** tree_estimate_probability (void)
*** 1293,1299 ****
    basic_block bb;
    struct loops loops_info;
  
!   flow_loops_find (&loops_info, LOOP_TREE);
    if (dump_file && (dump_flags & TDF_DETAILS))
      flow_loops_dump (&loops_info, dump_file, NULL, 0);
  
--- 1290,1296 ----
    basic_block bb;
    struct loops loops_info;
  
!   flow_loops_find (&loops_info);
    if (dump_file && (dump_flags & TDF_DETAILS))
      flow_loops_dump (&loops_info, dump_file, NULL, 0);
  
Index: tree-if-conv.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-if-conv.c,v
retrieving revision 2.27
diff -c -3 -p -r2.27 tree-if-conv.c
*** tree-if-conv.c	17 Feb 2005 16:19:41 -0000	2.27
--- tree-if-conv.c	21 Feb 2005 12:07:09 -0000
*************** static void combine_blocks (struct loop 
*** 126,132 ****
  static tree ifc_temp_var (tree, tree);
  static bool pred_blocks_visited_p (basic_block, bitmap *);
  static basic_block * get_loop_body_in_if_conv_order (const struct loop *loop);
! static bool bb_with_exit_edge_p (basic_block);
  
  /* List of basic blocks in if-conversion-suitable order.  */
  static basic_block *ifc_bbs;
--- 126,132 ----
  static tree ifc_temp_var (tree, tree);
  static bool pred_blocks_visited_p (basic_block, bitmap *);
  static basic_block * get_loop_body_in_if_conv_order (const struct loop *loop);
! static bool bb_with_exit_edge_p (struct loop *, basic_block);
  
  /* List of basic blocks in if-conversion-suitable order.  */
  static basic_block *ifc_bbs;
*************** tree_if_convert_cond_expr (struct loop *
*** 312,318 ****
    /* Now this conditional statement is redundant. Remove it.
       But, do not remove exit condition! Update exit condition
       using new condition.  */
!   if (!bb_with_exit_edge_p (bb_for_stmt (stmt)))
      {
        bsi_remove (bsi);
        cond = NULL_TREE;
--- 312,318 ----
    /* Now this conditional statement is redundant. Remove it.
       But, do not remove exit condition! Update exit condition
       using new condition.  */
!   if (!bb_with_exit_edge_p (loop, bb_for_stmt (stmt)))
      {
        bsi_remove (bsi);
        cond = NULL_TREE;
*************** if_convertible_modify_expr_p (struct loo
*** 405,411 ****
  
    if (TREE_CODE (TREE_OPERAND (m_expr, 0)) != SSA_NAME
        && bb != loop->header
!       && !bb_with_exit_edge_p (bb))
      {
        if (dump_file && (dump_flags & TDF_DETAILS))
  	{
--- 405,411 ----
  
    if (TREE_CODE (TREE_OPERAND (m_expr, 0)) != SSA_NAME
        && bb != loop->header
!       && !bb_with_exit_edge_p (loop, bb))
      {
        if (dump_file && (dump_flags & TDF_DETAILS))
  	{
*************** if_convertible_loop_p (struct loop *loop
*** 534,541 ****
        return false;
      }
  
-   flow_loop_scan (loop, LOOP_ALL);
- 
    /* If only one block, no need for if-conversion.  */
    if (loop->num_nodes <= 2)
      {
--- 534,539 ----
*************** if_convertible_loop_p (struct loop *loop
*** 545,551 ****
      }
  
    /* More than one loop exit is too much to handle.  */
!   if (loop->num_exits > 1)
      {
        if (dump_file && (dump_flags & TDF_DETAILS))
  	fprintf (dump_file, "multiple exits\n");
--- 543,549 ----
      }
  
    /* More than one loop exit is too much to handle.  */
!   if (!loop->single_exit)
      {
        if (dump_file && (dump_flags & TDF_DETAILS))
  	fprintf (dump_file, "multiple exits\n");
*************** if_convertible_loop_p (struct loop *loop
*** 557,564 ****
    /* If one of the loop header's edge is exit edge then do not apply
       if-conversion.  */
    FOR_EACH_EDGE (e, ei, loop->header->succs)
!     if ( e->flags & EDGE_LOOP_EXIT)
!       return false;
  
    compute_immediate_uses (TDFA_USE_OPS|TDFA_USE_VOPS, NULL);
  
--- 555,564 ----
    /* If one of the loop header's edge is exit edge then do not apply
       if-conversion.  */
    FOR_EACH_EDGE (e, ei, loop->header->succs)
!     {
!       if (loop_exit_edge_p (loop, e))
! 	return false;
!     }
  
    compute_immediate_uses (TDFA_USE_OPS|TDFA_USE_VOPS, NULL);
  
*************** if_convertible_loop_p (struct loop *loop
*** 593,599 ****
  	if (!if_convertible_phi_p (loop, bb, phi))
  	  return false;
  
!       if (bb_with_exit_edge_p (bb))
  	exit_bb_seen = true;
      }
  
--- 593,599 ----
  	if (!if_convertible_phi_p (loop, bb, phi))
  	  return false;
  
!       if (bb_with_exit_edge_p (loop, bb))
  	exit_bb_seen = true;
      }
  
*************** combine_blocks (struct loop *loop)
*** 874,880 ****
  
        bb = ifc_bbs[i];
  
!       if (!exit_bb && bb_with_exit_edge_p (bb))
  	  exit_bb = bb;
  
        if (bb == exit_bb)
--- 874,880 ----
  
        bb = ifc_bbs[i];
  
!       if (!exit_bb && bb_with_exit_edge_p (loop, bb))
  	  exit_bb = bb;
  
        if (bb == exit_bb)
*************** combine_blocks (struct loop *loop)
*** 890,900 ****
  	    {
  	      /* Redirect non-exit edge to loop->latch.  */
  	      FOR_EACH_EDGE (e, ei, bb->succs)
! 		if (!(e->flags & EDGE_LOOP_EXIT))
! 		  {
! 		    redirect_edge_and_branch (e, loop->latch);
! 		    set_immediate_dominator (CDI_DOMINATORS, loop->latch, bb);
! 		  }
  	    }
  	  continue;
  	}
--- 890,902 ----
  	    {
  	      /* Redirect non-exit edge to loop->latch.  */
  	      FOR_EACH_EDGE (e, ei, bb->succs)
! 		{
! 		  if (!loop_exit_edge_p (loop, e))
! 		    {
! 		      redirect_edge_and_branch (e, loop->latch);
! 		      set_immediate_dominator (CDI_DOMINATORS, loop->latch, bb);
! 		    }
! 		}
  	    }
  	  continue;
  	}
*************** get_loop_body_in_if_conv_order (const st
*** 1056,1072 ****
    return blocks;
  }
  
! /* Return true if one of the basic block BB edge is loop exit.  */
  
  static bool
! bb_with_exit_edge_p (basic_block bb)
  {
    edge e;
    edge_iterator ei;
    bool exit_edge_found = false;
  
    FOR_EACH_EDGE (e, ei, bb->succs)
!     if (e->flags & EDGE_LOOP_EXIT)
        {
  	exit_edge_found = true;
  	break;
--- 1058,1074 ----
    return blocks;
  }
  
! /* Return true if one of the basic block BB edge is exit of LOOP.  */
  
  static bool
! bb_with_exit_edge_p (struct loop *loop, basic_block bb)
  {
    edge e;
    edge_iterator ei;
    bool exit_edge_found = false;
  
    FOR_EACH_EDGE (e, ei, bb->succs)
!     if (loop_exit_edge_p (loop, e))
        {
  	exit_edge_found = true;
  	break;
Index: tree-loop-linear.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-loop-linear.c,v
retrieving revision 2.7
diff -c -3 -p -r2.7 tree-loop-linear.c
*** tree-loop-linear.c	17 Feb 2005 16:29:56 -0000	2.7
--- tree-loop-linear.c	21 Feb 2005 12:07:09 -0000
*************** linear_transform_loops (struct loops *lo
*** 277,285 ****
        depth = 1;
        for (temp = loop_nest->inner; temp; temp = temp->inner)
  	{
- 	  flow_loop_scan (temp, LOOP_ALL);
  	  /* If we have a sibling loop or multiple exit edges, jump ship.  */
! 	  if (temp->next || temp->num_exits != 1)
  	    {
  	      problem = true;
  	      break;
--- 277,284 ----
        depth = 1;
        for (temp = loop_nest->inner; temp; temp = temp->inner)
  	{
  	  /* If we have a sibling loop or multiple exit edges, jump ship.  */
! 	  if (temp->next || !temp->single_exit)
  	    {
  	      problem = true;
  	      break;
Index: tree-vect-analyze.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vect-analyze.c,v
retrieving revision 2.4
diff -c -3 -p -r2.4 tree-vect-analyze.c
*** tree-vect-analyze.c	20 Feb 2005 13:47:28 -0000	2.4
--- tree-vect-analyze.c	21 Feb 2005 12:07:09 -0000
*************** vect_analyze_operations (loop_vec_info l
*** 462,468 ****
                       "not vectorized: can't create epilog loop 1.");
            return false;
          }
!       if (!slpeel_can_duplicate_loop_p (loop, loop->exit_edges[0]))
          {
            if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
                                       LOOP_LOC (loop_vinfo)))
--- 462,468 ----
                       "not vectorized: can't create epilog loop 1.");
            return false;
          }
!       if (!slpeel_can_duplicate_loop_p (loop, loop->single_exit))
          {
            if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS,
                                       LOOP_LOC (loop_vinfo)))
*************** vect_analyze_loop_form (struct loop *loo
*** 2265,2271 ****
    loop_vec_info loop_vinfo;
    tree loop_cond;
    tree number_of_iterations = NULL;
-   bool rescan = false;
    LOC loop_loc;
  
    loop_loc = find_loop_location (loop);
--- 2265,2270 ----
*************** vect_analyze_loop_form (struct loop *loo
*** 2282,2289 ****
    
    if (!loop->single_exit 
        || loop->num_nodes != 2
!       || EDGE_COUNT (loop->header->preds) != 2
!       || loop->num_entries != 1)
      {
        if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
          {
--- 2281,2287 ----
    
    if (!loop->single_exit 
        || loop->num_nodes != 2
!       || EDGE_COUNT (loop->header->preds) != 2)
      {
        if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
          {
*************** vect_analyze_loop_form (struct loop *loo
*** 2293,2300 ****
              fprintf (vect_dump, "not vectorized: too many BBs in loop.");
            else if (EDGE_COUNT (loop->header->preds) != 2)
              fprintf (vect_dump, "not vectorized: too many incoming edges.");
-           else if (loop->num_entries != 1)
-             fprintf (vect_dump, "not vectorized: too many entries.");
          }
  
        return NULL;
--- 2291,2296 ----
*************** vect_analyze_loop_form (struct loop *loo
*** 2311,2326 ****
        return NULL;
      }
  
-   /* Make sure we have a preheader basic block.  */
-   if (!loop->pre_header || EDGE_COUNT (loop->pre_header->succs) != 1)
-     {
-       edge e = loop_preheader_edge (loop);
-       loop_split_edge_with (e, NULL);
-       if (vect_print_dump_info (REPORT_DETAILS, loop_loc))
- 	fprintf (vect_dump, "split preheader edge.");
-       rescan = true;
-     }
-     
    /* Make sure there exists a single-predecessor exit bb:  */
    if (EDGE_COUNT (loop->single_exit->dest->preds) != 1)
      {
--- 2307,2312 ----
*************** vect_analyze_loop_form (struct loop *loo
*** 2330,2336 ****
  	  loop_split_edge_with (e, NULL);
  	  if (vect_print_dump_info (REPORT_DETAILS, loop_loc))
  	    fprintf (vect_dump, "split exit edge.");
- 	  rescan = true;
  	}
        else
  	{
--- 2316,2321 ----
*************** vect_analyze_loop_form (struct loop *loo
*** 2339,2351 ****
  	  return NULL;
  	}
      }
-     
-   if (rescan)
-     {
-       flow_loop_scan (loop, LOOP_ALL);
-       /* Flow loop scan does not update loop->single_exit field.  */
-       loop->single_exit = loop->exit_edges[0];
-     }
  
    if (empty_block_p (loop->header))
      {
--- 2324,2329 ----
Index: tree-vect-transform.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vect-transform.c,v
retrieving revision 2.1
diff -c -3 -p -r2.1 tree-vect-transform.c
*** tree-vect-transform.c	17 Feb 2005 08:47:28 -0000	2.1
--- tree-vect-transform.c	21 Feb 2005 12:07:09 -0000
*************** vect_update_ivs_after_vectorizer (loop_v
*** 1315,1321 ****
  				  edge update_e)
  {
    struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
!   basic_block exit_bb = loop->exit_edges[0]->dest;
    tree phi, phi1;
    basic_block update_bb = update_e->dest;
  
--- 1315,1321 ----
  				  edge update_e)
  {
    struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
!   basic_block exit_bb = loop->single_exit->dest;
    tree phi, phi1;
    basic_block update_bb = update_e->dest;
  
*************** vect_do_peeling_for_loop_bound (loop_vec
*** 1398,1403 ****
--- 1398,1404 ----
    struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
    struct loop *new_loop;
    edge update_e;
+   basic_block preheader;
  #ifdef ENABLE_CHECKING
    int loop_num;
  #endif
*************** vect_do_peeling_for_loop_bound (loop_vec
*** 1413,1426 ****
    vect_generate_tmps_on_preheader (loop_vinfo, &ni_name,
  				   &ratio_mult_vf_name, ratio);
  
-   /* Update loop info.  */
-   loop->pre_header = loop_preheader_edge (loop)->src;
-   loop->pre_header_edges[0] = loop_preheader_edge (loop);
- 
  #ifdef ENABLE_CHECKING
    loop_num  = loop->num; 
  #endif
!   new_loop = slpeel_tree_peel_loop_to_edge (loop, loops, loop->exit_edges[0],
  					    ratio_mult_vf_name, ni_name, false);
  #ifdef ENABLE_CHECKING
    gcc_assert (new_loop);
--- 1414,1423 ----
    vect_generate_tmps_on_preheader (loop_vinfo, &ni_name,
  				   &ratio_mult_vf_name, ratio);
  
  #ifdef ENABLE_CHECKING
    loop_num  = loop->num; 
  #endif
!   new_loop = slpeel_tree_peel_loop_to_edge (loop, loops, loop->single_exit,
  					    ratio_mult_vf_name, ni_name, false);
  #ifdef ENABLE_CHECKING
    gcc_assert (new_loop);
*************** vect_do_peeling_for_loop_bound (loop_vec
*** 1434,1443 ****
       is a bb after NEW_LOOP, where these IVs are not used.  Find the edge that
       is on the path where the LOOP IVs are used and need to be updated.  */
  
!   if (EDGE_PRED (new_loop->pre_header, 0)->src == loop->exit_edges[0]->dest)
!     update_e = EDGE_PRED (new_loop->pre_header, 0);
    else
!     update_e = EDGE_PRED (new_loop->pre_header, 1);
  
    /* Update IVs of original loop as if they were advanced 
       by ratio_mult_vf_name steps.  */
--- 1431,1441 ----
       is a bb after NEW_LOOP, where these IVs are not used.  Find the edge that
       is on the path where the LOOP IVs are used and need to be updated.  */
  
!   preheader = loop_preheader_edge (new_loop)->src;
!   if (EDGE_PRED (preheader, 0)->src == loop->single_exit->dest)
!     update_e = EDGE_PRED (preheader, 0);
    else
!     update_e = EDGE_PRED (preheader, 1);
  
    /* Update IVs of original loop as if they were advanced 
       by ratio_mult_vf_name steps.  */
Index: tree-vectorizer.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vectorizer.c,v
retrieving revision 2.75
diff -c -3 -p -r2.75 tree-vectorizer.c
*** tree-vectorizer.c	17 Feb 2005 16:19:49 -0000	2.75
--- tree-vectorizer.c	21 Feb 2005 12:07:09 -0000
*************** slpeel_update_phis_for_duplicate_loop (s
*** 373,379 ****
    tree def;
    edge orig_loop_latch = loop_latch_edge (orig_loop);
    edge orig_entry_e = loop_preheader_edge (orig_loop);
!   edge new_loop_exit_e = new_loop->exit_edges[0];
    edge new_loop_entry_e = loop_preheader_edge (new_loop);
    edge entry_arg_e = (after ? orig_loop_latch : orig_entry_e);
  
--- 373,379 ----
    tree def;
    edge orig_loop_latch = loop_latch_edge (orig_loop);
    edge orig_entry_e = loop_preheader_edge (orig_loop);
!   edge new_loop_exit_e = new_loop->single_exit;
    edge new_loop_entry_e = loop_preheader_edge (new_loop);
    edge entry_arg_e = (after ? orig_loop_latch : orig_entry_e);
  
*************** slpeel_update_phi_nodes_for_guard (edge 
*** 518,525 ****
        if (entry_phis)
          {
            loop_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi,
!                                             EDGE_SUCC (loop->latch, 0));
!           guard_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, loop->entry_edges[0]);
          }
        else /* exit phis */
          {
--- 518,526 ----
        if (entry_phis)
          {
            loop_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi,
!                                             loop_latch_edge (loop));
!           guard_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi,
! 					     loop_preheader_edge (loop));
          }
        else /* exit phis */
          {
*************** slpeel_update_phi_nodes_for_guard (edge 
*** 544,550 ****
                loop_arg = orig_def;
              }
          }
!       add_phi_arg (new_phi, loop_arg, loop->exit_edges[0]);
        add_phi_arg (new_phi, guard_arg, guard_edge);
  
        /* 3. Update phi in successor block.  */
--- 545,551 ----
                loop_arg = orig_def;
              }
          }
!       add_phi_arg (new_phi, loop_arg, loop->single_exit);
        add_phi_arg (new_phi, guard_arg, guard_edge);
  
        /* 3. Update phi in successor block.  */
*************** slpeel_make_loop_iterate_ntimes (struct 
*** 567,573 ****
  {
    tree indx_before_incr, indx_after_incr, cond_stmt, cond;
    tree orig_cond;
!   edge exit_edge = loop->exit_edges[0];
    block_stmt_iterator loop_cond_bsi;
    block_stmt_iterator incr_bsi;
    bool insert_after;
--- 568,574 ----
  {
    tree indx_before_incr, indx_after_incr, cond_stmt, cond;
    tree orig_cond;
!   edge exit_edge = loop->single_exit;
    block_stmt_iterator loop_cond_bsi;
    block_stmt_iterator incr_bsi;
    bool insert_after;
*************** slpeel_tree_duplicate_loop_to_edge_cfg (
*** 636,642 ****
    basic_block exit_dest; 
    tree phi, phi_arg;
  
!   at_exit = (e == loop->exit_edges[0]); 
    if (!at_exit && e != loop_preheader_edge (loop))
      return NULL;
  
--- 637,643 ----
    basic_block exit_dest; 
    tree phi, phi_arg;
  
!   at_exit = (e == loop->single_exit); 
    if (!at_exit && e != loop_preheader_edge (loop))
      return NULL;
  
*************** slpeel_tree_duplicate_loop_to_edge_cfg (
*** 657,676 ****
        return NULL;
      }
  
!   exit_dest = loop->exit_edges[0]->dest;
    was_imm_dom = (get_immediate_dominator (CDI_DOMINATORS, 
  					  exit_dest) == loop->header ? 
  		 true : false);
  
    new_bbs = xmalloc (sizeof (basic_block) * loop->num_nodes);
  
!   copy_bbs (bbs, loop->num_nodes, new_bbs, NULL, 0, NULL, NULL);
  
    /* Duplicating phi args at exit bbs as coming 
       also from exit of duplicated loop.  */
    for (phi = phi_nodes (exit_dest); phi; phi = PHI_CHAIN (phi))
      {
!       phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, loop->exit_edges[0]);
        if (phi_arg)
  	{
  	  edge new_loop_exit_edge;
--- 658,678 ----
        return NULL;
      }
  
!   exit_dest = loop->single_exit->dest;
    was_imm_dom = (get_immediate_dominator (CDI_DOMINATORS, 
  					  exit_dest) == loop->header ? 
  		 true : false);
  
    new_bbs = xmalloc (sizeof (basic_block) * loop->num_nodes);
  
!   copy_bbs (bbs, loop->num_nodes, new_bbs,
! 	    &loop->single_exit, 1, &new_loop->single_exit, NULL);
  
    /* Duplicating phi args at exit bbs as coming 
       also from exit of duplicated loop.  */
    for (phi = phi_nodes (exit_dest); phi; phi = PHI_CHAIN (phi))
      {
!       phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, loop->single_exit);
        if (phi_arg)
  	{
  	  edge new_loop_exit_edge;
*************** slpeel_tree_duplicate_loop_to_edge_cfg (
*** 720,727 ****
        set_immediate_dominator (CDI_DOMINATORS, new_loop->header, preheader);
      }
  
-   flow_loop_scan (new_loop, LOOP_ALL);
-   flow_loop_scan (loop, LOOP_ALL);  
    free (new_bbs);
    free (bbs);
  
--- 722,727 ----
*************** slpeel_add_loop_guard (basic_block guard
*** 772,778 ****
  bool
  slpeel_can_duplicate_loop_p (struct loop *loop, edge e)
  {
!   edge exit_e = loop->exit_edges [0];
    edge entry_e = loop_preheader_edge (loop);
    tree orig_cond = get_loop_exit_condition (loop);
    block_stmt_iterator loop_exit_bsi = bsi_last (exit_e->src);
--- 772,778 ----
  bool
  slpeel_can_duplicate_loop_p (struct loop *loop, edge e)
  {
!   edge exit_e = loop->single_exit;
    edge entry_e = loop_preheader_edge (loop);
    tree orig_cond = get_loop_exit_condition (loop);
    block_stmt_iterator loop_exit_bsi = bsi_last (exit_e->src);
*************** slpeel_can_duplicate_loop_p (struct loop
*** 786,793 ****
        || !loop->outer
        || loop->num_nodes != 2
        || !empty_block_p (loop->latch)
!       || loop->num_exits != 1
!       || loop->num_entries != 1
        /* Verify that new loop exit condition can be trivially modified.  */
        || (!orig_cond || orig_cond != bsi_stmt (loop_exit_bsi))
        || (e != exit_e && e != entry_e))
--- 786,792 ----
        || !loop->outer
        || loop->num_nodes != 2
        || !empty_block_p (loop->latch)
!       || !loop->single_exit
        /* Verify that new loop exit condition can be trivially modified.  */
        || (!orig_cond || orig_cond != bsi_stmt (loop_exit_bsi))
        || (e != exit_e && e != entry_e))
*************** void
*** 801,808 ****
  slpeel_verify_cfg_after_peeling (struct loop *first_loop,
                                   struct loop *second_loop)
  {
!   basic_block loop1_exit_bb = first_loop->exit_edges[0]->dest;
!   basic_block loop2_entry_bb = second_loop->pre_header;
    basic_block loop1_entry_bb = loop_preheader_edge (first_loop)->src;
  
    /* A guard that controls whether the second_loop is to be executed or skipped
--- 800,807 ----
  slpeel_verify_cfg_after_peeling (struct loop *first_loop,
                                   struct loop *second_loop)
  {
!   basic_block loop1_exit_bb = first_loop->single_exit->dest;
!   basic_block loop2_entry_bb = loop_preheader_edge (second_loop)->src;
    basic_block loop1_entry_bb = loop_preheader_edge (first_loop)->src;
  
    /* A guard that controls whether the second_loop is to be executed or skipped
*************** slpeel_verify_cfg_after_peeling (struct 
*** 812,818 ****
     */
    gcc_assert (EDGE_COUNT (loop1_exit_bb->succs) == 2);
     
-    
    /* 1. Verify that one of the successors of first_loopt->exit is the preheader
          of second_loop.  */
     
--- 811,816 ----
*************** slpeel_tree_peel_loop_to_edge (struct lo
*** 880,886 ****
    basic_block bb_before_second_loop, bb_after_second_loop;
    basic_block bb_before_first_loop;
    basic_block bb_between_loops;
!   edge exit_e = loop->exit_edges [0];
    LOC loop_loc;
    
    if (!slpeel_can_duplicate_loop_p (loop, e))
--- 878,884 ----
    basic_block bb_before_second_loop, bb_after_second_loop;
    basic_block bb_before_first_loop;
    basic_block bb_between_loops;
!   edge exit_e = loop->single_exit;
    LOC loop_loc;
    
    if (!slpeel_can_duplicate_loop_p (loop, e))
*************** slpeel_tree_peel_loop_to_edge (struct lo
*** 961,970 ****
  
    bb_before_first_loop = split_edge (loop_preheader_edge (first_loop));
    add_bb_to_loop (bb_before_first_loop, first_loop->outer);
!   bb_before_second_loop = split_edge (first_loop->exit_edges[0]);
    add_bb_to_loop (bb_before_second_loop, first_loop->outer);
-   flow_loop_scan (first_loop, LOOP_ALL);
-   flow_loop_scan (second_loop, LOOP_ALL);
  
    pre_condition =
          build2 (LE_EXPR, boolean_type_node, first_niters, integer_zero_node);
--- 959,966 ----
  
    bb_before_first_loop = split_edge (loop_preheader_edge (first_loop));
    add_bb_to_loop (bb_before_first_loop, first_loop->outer);
!   bb_before_second_loop = split_edge (first_loop->single_exit);
    add_bb_to_loop (bb_before_second_loop, first_loop->outer);
  
    pre_condition =
          build2 (LE_EXPR, boolean_type_node, first_niters, integer_zero_node);
*************** slpeel_tree_peel_loop_to_edge (struct lo
*** 1000,1011 ****
          orig_exit_bb:
     */
  
!   bb_between_loops = split_edge (first_loop->exit_edges[0]);
    add_bb_to_loop (bb_between_loops, first_loop->outer);
!   bb_after_second_loop = split_edge (second_loop->exit_edges[0]);
    add_bb_to_loop (bb_after_second_loop, second_loop->outer);
-   flow_loop_scan (first_loop, LOOP_ALL);
-   flow_loop_scan (second_loop, LOOP_ALL);
  
    pre_condition = build2 (EQ_EXPR, boolean_type_node, first_niters, niters);
    skip_e = slpeel_add_loop_guard (bb_between_loops, pre_condition,
--- 996,1005 ----
          orig_exit_bb:
     */
  
!   bb_between_loops = split_edge (first_loop->single_exit);
    add_bb_to_loop (bb_between_loops, first_loop->outer);
!   bb_after_second_loop = split_edge (second_loop->single_exit);
    add_bb_to_loop (bb_after_second_loop, second_loop->outer);
  
    pre_condition = build2 (EQ_EXPR, boolean_type_node, first_niters, niters);
    skip_e = slpeel_add_loop_guard (bb_between_loops, pre_condition,
*************** slpeel_tree_peel_loop_to_edge (struct lo
*** 1014,1021 ****
                                       second_loop == new_loop);
  
    /* Flow loop scan does not update loop->single_exit field.  */
!   first_loop->single_exit = first_loop->exit_edges[0];
!   second_loop->single_exit = second_loop->exit_edges[0];
  
    /* 4. Make first-loop iterate FIRST_NITERS times, if requested.
     */
--- 1008,1015 ----
                                       second_loop == new_loop);
  
    /* Flow loop scan does not update loop->single_exit field.  */
!   first_loop->single_exit = first_loop->single_exit;
!   second_loop->single_exit = second_loop->single_exit;
  
    /* 4. Make first-loop iterate FIRST_NITERS times, if requested.
     */


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