This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[rtlopt] peeling heuristics tweak
- From: Zdenek Dvorak <rakdver at atrey dot karlin dot mff dot cuni dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Cc: jh at suse dot cz
- Date: Fri, 29 Nov 2002 14:23:15 +0100
- Subject: [rtlopt] peeling heuristics tweak
Hello,
some of the regressions of new peeling pass were caused by increased
number of misspredicted branches. This patch forbids simple peeling (and
unrolling) of loops that contain branches in hope (supported by some
measuring) that it will improve the situation.
Zdenek
Changelog:
* cfgloopanal.c (simple_loop_p): Count desc->n_branches.
* cfgloop.h (struct loop_desc): Add n_branches field.
* loop-unroll.c (decide_peel_simple, decide_unroll_stupid): Do not
unroll/peel loops containing branches.
Index: cfgloopanal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/cfgloopanal.c,v
retrieving revision 1.1.4.5
diff -c -3 -p -r1.1.4.5 cfgloopanal.c
*** cfgloopanal.c 9 Nov 2002 17:52:10 -0000 1.1.4.5
--- cfgloopanal.c 29 Nov 2002 13:08:10 -0000
*************** simple_loop_p (loops, loop, desc)
*** 740,745 ****
--- 740,746 ----
regset invariant_regs;
regset_head invariant_regs_head;
rtx *single_set_regs;
+ int n_branches;
body = get_loop_body (loop);
*************** simple_loop_p (loops, loop, desc)
*** 749,754 ****
--- 750,756 ----
blocks_invariant_registers (body, loop->num_nodes, invariant_regs);
blocks_single_set_registers (body, loop->num_nodes, single_set_regs);
+ n_branches = 0;
for (i = 0; i < loop->num_nodes; i++)
{
for (e = body[i]->succ; e; e = e->succ_next)
*************** simple_loop_p (loops, loop, desc)
*** 764,770 ****
--- 766,776 ----
continue;
*desc = act;
}
+
+ if (body[i]->succ && body[i]->succ->succ_next)
+ n_branches++;
}
+ desc->n_branches = n_branches;
if (rtl_dump_file && any)
{
*************** simple_loop_p (loops, loop, desc)
*** 797,802 ****
--- 803,812 ----
if (desc->neg)
fprintf (rtl_dump_file, "(negated)");
fprintf (rtl_dump_file, "%s\n", GET_RTX_NAME (desc->cond));
+
+ fprintf (rtl_dump_file, "; Number of branches:");
+ fprintf (rtl_dump_file, "%d\n", desc->n_branches);
+
fputc ('\n', rtl_dump_file);
}
Index: cfgloop.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/cfgloop.h,v
retrieving revision 1.1.2.4
diff -c -3 -p -r1.1.2.4 cfgloop.h
*** cfgloop.h 9 Nov 2002 17:52:11 -0000 1.1.2.4
--- cfgloop.h 29 Nov 2002 13:08:10 -0000
*************** struct loop_desc
*** 53,58 ****
--- 53,59 ----
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. */
+ int n_branches; /* Number of branches inside the loop. */
};
/* Structure to hold information for each natural loop. */
Index: loop-unroll.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/loop-unroll.c,v
retrieving revision 1.1.2.13
diff -c -3 -p -r1.1.2.13 loop-unroll.c
*** loop-unroll.c 10 Nov 2002 13:49:32 -0000 1.1.2.13
--- loop-unroll.c 29 Nov 2002 13:08:10 -0000
*************** decide_peel_simple (loops, loop, flags)
*** 901,913 ****
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)
{
--- 901,922 ----
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;
}
+ /* Do not simply peel loops with branches inside -- it increases number
+ of mispredicts. */
+ if (loop->desc.n_branches > 1)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not peeling, contains branches\n");
+ return;
+ }
+
/* If we have profile feedback, check whether the loop rolls. */
if (loop->histogram)
{
*************** decide_unroll_stupid (loops, loop, flags
*** 1034,1039 ****
--- 1043,1057 ----
{
if (rtl_dump_file)
fprintf (rtl_dump_file, ";; The loop is simple\n");
+ return;
+ }
+
+ /* Do not unroll loops with branches inside -- it increases number
+ of mispredicts. */
+ if (loop->desc.n_branches > 1)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not unrolling, contains branches\n");
return;
}