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>
* combine.c (can_change_dest_mode): New function.
......
......@@ -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 *);
......
......@@ -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
......
......@@ -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);
......
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.
......
/* { 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,
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);
......
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