This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Changes to enable peeling non-innermost loops
- From: Zdenek Dvorak <rakdver at atrey dot karlin dot mff dot cuni dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 10 Nov 2006 00:36:54 +0100
- Subject: [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
}