Commit 519cac4a by Jan Hubicka Committed by Jan Hubicka

cfgloopanal.c (get_loop_hot_path): New function.

	* cfgloopanal.c (get_loop_hot_path): New function.
	* tree-ssa-lop-ivcanon.c (struct loop_size): Add CONSTANT_IV,
	NUM_NON_PURE_CALLS_ON_HOT_PATH, NUM_PURE_CALLS_ON_HOT_PATH,
	NUM_BRANCHES_ON_HOT_PATH.
	(tree_estimate_loop_size): Compute the new values.
	(try_unroll_loop_completely): Disable unrolling of loops with only
	calls or too many branches.
	(tree_unroll_loops_completely): Deal also with outer loops of hot loops.
	* cfgloop.h (get_loop_hot_path): Declare.
	* params.def (PARAM_MAX_PEEL_BRANCHES): New parameters.
	* invoke.texi (max-peel-branches): Document.

	* gcc.dg/tree-ssa/loop-1.c: Make to look like a good unroling candidate still.
	* gcc.dg/tree-ssa/loop-23.c: Likewise.
	* gcc.dg/tree-ssa/cunroll-1.c: Unrolling now happens early.
	* gcc.dg/tree-prof/unroll-1.c: Remove confused dg-options.

From-SVN: r193246
parent 425b784f
......@@ -714,6 +714,7 @@ extern void doloop_optimize_loops (void);
extern void move_loop_invariants (void);
extern bool finite_loop_p (struct loop *);
extern void scale_loop_profile (struct loop *loop, int scale, int iteration_bound);
extern VEC (basic_block, heap) * get_loop_hot_path (const struct loop *loop);
/* Returns the outermost loop of the loop nest that contains LOOP.*/
static inline struct loop *
......
......@@ -483,3 +483,36 @@ single_likely_exit (struct loop *loop)
VEC_free (edge, heap, exits);
return found;
}
/* Gets basic blocks of a LOOP. Header is the 0-th block, rest is in dfs
order against direction of edges from latch. Specially, if
header != latch, latch is the 1-st block. */
VEC (basic_block, heap) *
get_loop_hot_path (const struct loop *loop)
{
basic_block bb = loop->header;
VEC (basic_block, heap) *path = NULL;
bitmap visited = BITMAP_ALLOC (NULL);
while (true)
{
edge_iterator ei;
edge e;
edge best = NULL;
VEC_safe_push (basic_block, heap, path, bb);
bitmap_set_bit (visited, bb->index);
FOR_EACH_EDGE (e, ei, bb->succs)
if ((!best || e->probability > best->probability)
&& !loop_exit_edge_p (loop, e)
&& !bitmap_bit_p (visited, e->dest->index))
best = e;
if (!best || best->dest == loop->header)
break;
bb = best->dest;
}
BITMAP_FREE (visited);
return path;
}
......@@ -9085,6 +9085,9 @@ the loop code is peeled.
@item max-peel-times
The maximum number of peelings of a single loop.
@item max-peel-branches
The maximum number of branches on the hot path through the peeled sequence.
@item max-completely-peeled-insns
The maximum number of insns of a completely peeled loop.
......
......@@ -291,6 +291,11 @@ DEFPARAM(PARAM_MAX_PEEL_TIMES,
"max-peel-times",
"The maximum number of peelings of a single loop",
16, 0, 0)
/* The maximum number of peelings of a single loop that is peeled completely. */
DEFPARAM(PARAM_MAX_PEEL_BRANCHES,
"max-peel-branches",
"The maximum number of branches on the path through the peeled sequence",
32, 0, 0)
/* The maximum number of insns of a peeled loop. */
DEFPARAM(PARAM_MAX_COMPLETELY_PEELED_INSNS,
"max-completely-peeled-insns",
......
2012-11-06 Jan Hubicka <jh@suse.cz>
* gcc.dg/tree-ssa/loop-1.c: Make to look like a good unroling candidate still.
* gcc.dg/tree-ssa/loop-23.c: Likewise.
* gcc.dg/tree-ssa/cunroll-1.c: Unrolling now happens early.
* gcc.dg/tree-prof/unroll-1.c: Remove confused dg-options.
2012-11-06 David Edelsohn <dje.gcc@gmail.com>
* const-uniq-1.c: Expand regex to match AIX XCOFF labels.
......
......@@ -21,4 +21,3 @@ main()
}
/* { dg-final-use { scan-rtl-dump "Considering unrolling loop with constant number of iterations" "loop2_unroll" } } */
/* { dg-final-use { cleanup-rtl-dump "Not unrolling loop, doesn't roll" } } */
/* { dg-options "-O3 -fdump-rtl-loop2_unroll -funroll-loops -fno-peel-loops" } */
/* { dg-do compile } */
/* { dg-options "-O3 -fdump-tree-cunroll-details" } */
/* { dg-options "-O3 -fdump-tree-cunrolli-details" } */
int a[2];
test(int c)
{
......@@ -10,4 +10,4 @@ test(int c)
/* Array bounds says the loop will not roll much. */
/* { dg-final { scan-tree-dump "Unrolled loop 1 completely .duplicated 1 times.." "cunroll"} } */
/* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "cunroll"} } */
/* { dg-final { cleanup-tree-dump "cunroll" } } */
/* { dg-final { cleanup-tree-dump "cunrolli" } } */
......@@ -17,13 +17,16 @@
to the load from the GOT this also contains the name of the funtion so for
each call the function name would appear twice. */
/* { dg-options "-O1 -ftree-loop-ivcanon -funroll-loops -fdump-tree-ivcanon-details -fdump-tree-cunroll-details -fdump-tree-optimized -mno-relax-pic-calls" { target mips*-*-* } } */
void xxx(void)
__attribute__ ((pure))
int foo (int x);
int xxx(void)
{
int x = 45;
int sum;
while (x >>= 1)
foo ();
sum += foo (x) * 2;
return sum;
}
/* We should be able to find out that the loop iterates four times and unroll it completely. */
......
/* { dg-do compile } */
/* { dg-options "-O2 -funroll-loops -fdump-tree-cunroll-details" } */
void bla(int);
__attribute__ ((pure))
int bla(int);
void foo(void)
int foo(void)
{
int i;
int sum;
/* This loop used to appear to be too large for unrolling. */
for (i = 0; i < 4; i++)
{
bla (i);
bla (2*i);
bla (3*i);
bla (4*i);
bla (5*i);
bla (6*i);
bla (7*i);
bla (8*i);
sum += bla (i);
sum += bla (2*i);
sum += bla (3*i);
sum += bla (4*i);
sum += bla (5*i);
sum += bla (6*i);
sum += bla (7*i);
sum += bla (8*i);
}
return sum;
}
/* { dg-final { scan-tree-dump-times "Unrolled loop 1 completely" 1 "cunroll" } } */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment