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] Changes to enable peeling non-innermost loops


Hello,

this patch is needed in the "Prefetching Improvements" project to enable
peeling non-innermost loops.  A bit to my surprise, almost everything
seems to work just fine, only the single exit information needs to be
updated.

Bootstrapped & regtested on i686.

Zdenek

	* cfgloopmanip.c (update_single_exit_for_duplicated_loop,
	update_single_exit_for_duplicated_loops): New functions.
	(duplicate_loop_to_header_edge): Use
	update_single_exit_for_duplicated_loops.
	* tree-ssa-loop-manip.c (tree_unroll_loop): Call verification
	functions only with ENABLE_CHECKING.

Index: cfgloopmanip.c
===================================================================
*** cfgloopmanip.c	(revision 118545)
--- cfgloopmanip.c	(working copy)
*************** update_single_exits_after_duplication (b
*** 770,775 ****
--- 770,809 ----
      bbs[i]->flags &= ~BB_DUPLICATED;
  }
  
+ /* Updates single exit information for the copy of LOOP.  */
+ 
+ static void
+ update_single_exit_for_duplicated_loop (struct loop *loop)
+ {
+   struct loop *copy = loop->copy;
+   basic_block src, dest;
+   edge exit = loop->single_exit;
+ 
+   if (!exit)
+     return;
+ 
+   src = get_bb_copy (exit->src);
+   dest = exit->dest;
+   if (dest->flags & BB_DUPLICATED)
+     dest = get_bb_copy (dest);
+ 
+   exit = find_edge (src, dest);
+   gcc_assert (exit != NULL);
+   copy->single_exit = exit;
+ }
+ 
+ /* Updates single exit information for copies of ORIG_LOOPS and their subloops.
+    N is the number of the loops in the ORIG_LOOPS array.  */
+ 
+ static void
+ update_single_exit_for_duplicated_loops (struct loop *orig_loops[], unsigned n)
+ {
+   unsigned i;
+ 
+   for (i = 0; i < n; i++)
+     update_single_exit_for_duplicated_loop (orig_loops[i]);
+ }
+ 
  /* Duplicates body of LOOP to given edge E NDUPL times.  Takes care of updating
     LOOPS structure and dominators.  E's destination must be LOOP header for
     this to work, i.e. it must be entry or latch edge of this loop; these are
*************** duplicate_loop_to_header_edge (struct lo
*** 950,955 ****
--- 984,998 ----
  		place_after);
        place_after = new_spec_edges[SE_LATCH]->src;
  
+       if (loops->state & LOOPS_HAVE_MARKED_SINGLE_EXITS)
+ 	{
+ 	  for (i = 0; i < n; i++)
+ 	    bbs[i]->flags |= BB_DUPLICATED;
+ 	  update_single_exit_for_duplicated_loops (orig_loops, n_orig_loops);
+ 	  for (i = 0; i < n; i++)
+ 	    bbs[i]->flags &= ~BB_DUPLICATED;
+ 	}
+ 
        if (flags & DLTHE_RECORD_COPY_NUMBER)
  	for (i = 0; i < n; i++)
  	  {
Index: tree-ssa-loop-manip.c
===================================================================
*** tree-ssa-loop-manip.c	(revision 118545)
--- tree-ssa-loop-manip.c	(working copy)
*************** tree_unroll_loop (struct loops *loops, s
*** 940,947 ****
--- 940,949 ----
  			   tree_block_label (rest));
    bsi_insert_after (&bsi, exit_if, BSI_NEW_STMT);
  
+ #ifdef ENABLE_CHECKING
    verify_flow_info ();
    verify_dominators (CDI_DOMINATORS);
    verify_loop_structure (loops);
    verify_loop_closed_ssa ();
+ #endif
  }


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