Commit 178df94f by Jan Hubicka Committed by Jan Hubicka

cfgloop.h (DLTHE_FLAG_COMPLETTE_PEEL): New flag.


	* 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.

From-SVN: r102687
parent 4164b2fb
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> 2005-08-03 Paul Brook <paul@codesourcery.com>
* combine.c (can_change_dest_mode): New function. * combine.c (can_change_dest_mode): New function.
......
...@@ -298,6 +298,8 @@ extern bool can_duplicate_loop_p (struct loop *loop); ...@@ -298,6 +298,8 @@ extern bool can_duplicate_loop_p (struct loop *loop);
duplicate_loop_to_header_edge. */ duplicate_loop_to_header_edge. */
#define DLTHE_RECORD_COPY_NUMBER 2 /* Record copy number in the aux #define DLTHE_RECORD_COPY_NUMBER 2 /* Record copy number in the aux
field of newly create BB. */ 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 *, extern struct loop * duplicate_loop (struct loops *, struct loop *,
struct loop *); struct loop *);
......
...@@ -913,7 +913,28 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops, ...@@ -913,7 +913,28 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
? prob_pass_wont_exit ? prob_pass_wont_exit
: prob_pass_thru; : 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_main = TEST_BIT (wont_exit, 0)
? prob_pass_wont_exit ? prob_pass_wont_exit
......
...@@ -520,6 +520,7 @@ peel_loop_completely (struct loops *loops, struct loop *loop) ...@@ -520,6 +520,7 @@ peel_loop_completely (struct loops *loops, struct loop *loop)
wont_exit, desc->out_edge, wont_exit, desc->out_edge,
remove_edges, &n_remove_edges, remove_edges, &n_remove_edges,
DLTHE_FLAG_UPDATE_FREQ DLTHE_FLAG_UPDATE_FREQ
| DLTHE_FLAG_COMPLETTE_PEEL
| (opt_info | (opt_info
? DLTHE_RECORD_COPY_NUMBER : 0)); ? DLTHE_RECORD_COPY_NUMBER : 0));
gcc_assert (ok); gcc_assert (ok);
......
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> 2005-08-02 David Edelsohn <edelsohn@gnu.org>
* gfortran.dg/constant_substring.f: New test. * gfortran.dg/constant_substring.f: New test.
......
/* { 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" } } */
/* { 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" } } */
...@@ -223,20 +223,35 @@ try_unroll_loop_completely (struct loops *loops ATTRIBUTE_UNUSED, ...@@ -223,20 +223,35 @@ try_unroll_loop_completely (struct loops *loops ATTRIBUTE_UNUSED,
if (n_unroll) 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); old_cond = COND_EXPR_COND (cond);
COND_EXPR_COND (cond) = dont_exit; COND_EXPR_COND (cond) = dont_exit;
update_stmt (cond); update_stmt (cond);
initialize_original_copy_tables (); 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), if (!tree_duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
loops, n_unroll, NULL, loops, n_unroll, wont_exit,
NULL, NULL, NULL, 0)) exit, edges_to_remove,
&n_to_remove,
DLTHE_FLAG_UPDATE_FREQ
| DLTHE_FLAG_COMPLETTE_PEEL))
{ {
COND_EXPR_COND (cond) = old_cond; COND_EXPR_COND (cond) = old_cond;
update_stmt (cond); update_stmt (cond);
free_original_copy_tables (); free_original_copy_tables ();
free (wont_exit);
free (edges_to_remove);
return false; return false;
} }
free (wont_exit);
free (edges_to_remove);
free_original_copy_tables (); free_original_copy_tables ();
} }
...@@ -350,7 +365,7 @@ tree_unroll_loops_completely (struct loops *loops, bool may_increase_size) ...@@ -350,7 +365,7 @@ tree_unroll_loops_completely (struct loops *loops, bool may_increase_size)
unsigned i; unsigned i;
struct loop *loop; struct loop *loop;
bool changed = false; 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++) for (i = 1; i < loops->num; i++)
{ {
...@@ -359,6 +374,10 @@ tree_unroll_loops_completely (struct loops *loops, bool may_increase_size) ...@@ -359,6 +374,10 @@ tree_unroll_loops_completely (struct loops *loops, bool may_increase_size)
if (!loop) if (!loop)
continue; 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, changed |= canonicalize_loop_induction_variables (loops, loop,
false, ul, false, ul,
!flag_tree_loop_ivcanon); !flag_tree_loop_ivcanon);
......
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