diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-08-03 13:34:49 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-08-03 13:34:49 +0000 |
commit | fb54ef7ccb98fc1c10a1662869dab0a3ab52a35a (patch) | |
tree | 1a926b9bc202452ffb1c89f9db59da5c72ea357e /gcc | |
parent | 136305f40bec39c518bec801bcb454cf483005f3 (diff) | |
download | gcc-fb54ef7ccb98fc1c10a1662869dab0a3ab52a35a.tar.gz |
* cfgloop.h (DLTHE_FLAG_COMPLETTE_PEEL): New flag.
* cfgloopmanip.c (duplicate_loop_to_header_edge): Special case
profile updating for complette unrolling.
* loop-unroll.c (peel_loop_completely): Use it.
* tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Likewise.
(tree_unroll_loops_completely): Disable code growing unrolling of cold
loops.
* update-conroll.c: New testcase.
* update-conroll-2.c: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@102687 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cfgloop.h | 2 | ||||
-rw-r--r-- | gcc/cfgloopmanip.c | 23 | ||||
-rw-r--r-- | gcc/loop-unroll.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-prof/update-cunroll-2.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/update-cunroll.c | 13 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-ivcanon.c | 25 |
8 files changed, 96 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fb1cf3fd7cc..21d87f21c64 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2005-08-03 Jan Hubicka <jh@suse.cz> + + * cfgloop.h (DLTHE_FLAG_COMPLETTE_PEEL): New flag. + * cfgloopmanip.c (duplicate_loop_to_header_edge): Special case + profile updating for complette unrolling. + * loop-unroll.c (peel_loop_completely): Use it. + * tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Likewise. + (tree_unroll_loops_completely): Disable code growing unrolling of cold + loops. + 2005-08-03 Paul Brook <paul@codesourcery.com> * combine.c (can_change_dest_mode): New function. diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index 34cebe2ce3c..0bfb8d87a9e 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -298,6 +298,8 @@ extern bool can_duplicate_loop_p (struct loop *loop); duplicate_loop_to_header_edge. */ #define DLTHE_RECORD_COPY_NUMBER 2 /* Record copy number in the aux field of newly create BB. */ +#define DLTHE_FLAG_COMPLETTE_PEEL 4 /* Update frequencies expecting + a complette peeling. */ extern struct loop * duplicate_loop (struct loops *, struct loop *, struct loop *); diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c index 648e8372ff8..1e364279403 100644 --- a/gcc/cfgloopmanip.c +++ b/gcc/cfgloopmanip.c @@ -913,7 +913,28 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops, ? prob_pass_wont_exit : prob_pass_thru; - if (is_latch) + /* Complette peeling is special as the probability of exit in last + copy becomes 1. */ + if (flags & DLTHE_FLAG_COMPLETTE_PEEL) + { + int wanted_freq = EDGE_FREQUENCY (e); + + if (wanted_freq > freq_in) + wanted_freq = freq_in; + + gcc_assert (!is_latch); + /* First copy has frequency of incomming edge. Each subseqeuent + frequency should be reduced by prob_pass_wont_exit. Caller + should've managed the flags so all except for original loop + has won't exist set. */ + scale_act = RDIV (wanted_freq * REG_BR_PROB_BASE, freq_in); + /* Now simulate the duplication adjustments and compute header + frequency of the last copy. */ + for (i = 0; i < ndupl; i++) + wanted_freq = RDIV (wanted_freq * scale_step[i], REG_BR_PROB_BASE); + scale_main = RDIV (wanted_freq * REG_BR_PROB_BASE, freq_in); + } + else if (is_latch) { prob_pass_main = TEST_BIT (wont_exit, 0) ? prob_pass_wont_exit diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c index deeca2da8d6..8293448f5cf 100644 --- a/gcc/loop-unroll.c +++ b/gcc/loop-unroll.c @@ -520,6 +520,7 @@ peel_loop_completely (struct loops *loops, struct loop *loop) wont_exit, desc->out_edge, remove_edges, &n_remove_edges, DLTHE_FLAG_UPDATE_FREQ + | DLTHE_FLAG_COMPLETTE_PEEL | (opt_info ? DLTHE_RECORD_COPY_NUMBER : 0)); gcc_assert (ok); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4db6413d193..e571c94ecab 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-08-03 Jan Hubicka <jh@suse.cz> + + * update-conroll.c: New testcase. + * update-conroll-2.c: New testcase. + 2005-08-02 David Edelsohn <edelsohn@gnu.org> * gfortran.dg/constant_substring.f: New test. diff --git a/gcc/testsuite/gcc.dg/tree-prof/update-cunroll-2.c b/gcc/testsuite/gcc.dg/tree-prof/update-cunroll-2.c new file mode 100644 index 00000000000..d559b924535 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/update-cunroll-2.c @@ -0,0 +1,21 @@ + +/* { dg-options "-O2 -fdump-tree-optimized-blocks" } */ +int a[8]; +__attribute__ ((noinline)) +int t() +{ + int i; + for (i = 0; i < 3; i++) + if (a[i]) + break; + return i; +} +main () +{ + int i; + for (i = 0; i < 1000; i++) + t (); + return 0; +} +/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ +/* { dg-final-use { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/update-cunroll.c b/gcc/testsuite/gcc.dg/tree-ssa/update-cunroll.c new file mode 100644 index 00000000000..7a114ea3a9c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/update-cunroll.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +int a[8]; +int t() +{ + int i; + for (i = 0; i < 3; i++) + if (a[i]) + break; + return i; +} +/* { dg-final { scan-tree-dump-times ".optimized" 0 "Invalid sum"} } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c index e8a94d66e6c..4ac20039f4c 100644 --- a/gcc/tree-ssa-loop-ivcanon.c +++ b/gcc/tree-ssa-loop-ivcanon.c @@ -223,20 +223,35 @@ try_unroll_loop_completely (struct loops *loops ATTRIBUTE_UNUSED, if (n_unroll) { + sbitmap wont_exit; + edge *edges_to_remove = xmalloc (sizeof (edge *) * n_unroll); + unsigned int n_to_remove = 0; + old_cond = COND_EXPR_COND (cond); COND_EXPR_COND (cond) = dont_exit; update_stmt (cond); initialize_original_copy_tables (); + wont_exit = sbitmap_alloc (n_unroll + 1); + sbitmap_ones (wont_exit); + RESET_BIT (wont_exit, 0); + if (!tree_duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop), - loops, n_unroll, NULL, - NULL, NULL, NULL, 0)) + loops, n_unroll, wont_exit, + exit, edges_to_remove, + &n_to_remove, + DLTHE_FLAG_UPDATE_FREQ + | DLTHE_FLAG_COMPLETTE_PEEL)) { COND_EXPR_COND (cond) = old_cond; update_stmt (cond); free_original_copy_tables (); + free (wont_exit); + free (edges_to_remove); return false; } + free (wont_exit); + free (edges_to_remove); free_original_copy_tables (); } @@ -350,7 +365,7 @@ tree_unroll_loops_completely (struct loops *loops, bool may_increase_size) unsigned i; struct loop *loop; bool changed = false; - enum unroll_level ul = may_increase_size ? UL_ALL : UL_NO_GROWTH; + enum unroll_level ul; for (i = 1; i < loops->num; i++) { @@ -359,6 +374,10 @@ tree_unroll_loops_completely (struct loops *loops, bool may_increase_size) if (!loop) continue; + if (may_increase_size && maybe_hot_bb_p (loop->header)) + ul = UL_ALL; + else + ul = UL_NO_GROWTH; changed |= canonicalize_loop_induction_variables (loops, loop, false, ul, !flag_tree_loop_ivcanon); |