diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-03-18 20:15:06 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-03-18 20:15:06 +0000 |
commit | 4d6b11ab420f373787b369905fe1271927ae671c (patch) | |
tree | c8155205eea9acda3648c08b1f00c2d20be9270e /gcc/tree-ssa-loop-ch.c | |
parent | 2c191cc3f2f5ebcb6054b344f1ae08cfcd8fe516 (diff) | |
download | gcc-4d6b11ab420f373787b369905fe1271927ae671c.tar.gz |
* basic-block.h (scale_bbs_frequencies_int,
scale_bbs_frequencies_gcov_type): Declare.
* cfg.c (RDIV): New macro.
(update_bb_frequency_for_threading): Fix.
* basic-block.h (scale_bbs_frequencies_int,
scale_bbs_frequencies_gcov_type): New.
* cfgloopmanip.c (scale_bbs_frequencies): Kill.
(scale_loop_frequencies, duplicate_loop_to_header_edge): Use
scale_bbs_frequencies_int.
* tree-ssa-loop-ch.c (copy_loop_headers): Fix profiling info.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@96700 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-loop-ch.c')
-rw-r--r-- | gcc/tree-ssa-loop-ch.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c index 6d122711db7..fb5f7f68fb5 100644 --- a/gcc/tree-ssa-loop-ch.c +++ b/gcc/tree-ssa-loop-ch.c @@ -127,9 +127,11 @@ copy_loop_headers (void) unsigned i; struct loop *loop; basic_block header; - edge exit; - basic_block *bbs; + edge exit, entry; + basic_block *bbs, *copied_bbs; unsigned n_bbs; + unsigned bbs_size; + gcov_type entry_count, body_count, total_count; loops = loop_optimizer_init (dump_file); if (!loops) @@ -145,6 +147,8 @@ copy_loop_headers (void) #endif bbs = xmalloc (sizeof (basic_block) * n_basic_blocks); + copied_bbs = xmalloc (sizeof (basic_block) * n_basic_blocks); + bbs_size = n_basic_blocks; for (i = 1; i < loops->num; i++) { @@ -180,6 +184,7 @@ copy_loop_headers (void) else exit = EDGE_SUCC (header, 1); bbs[n_bbs++] = header; + gcc_assert (bbs_size > n_bbs); header = exit->dest; } @@ -196,13 +201,33 @@ copy_loop_headers (void) if (!single_pred_p (exit->dest)) exit = single_succ_edge (loop_split_edge_with (exit, NULL)); - if (!tree_duplicate_sese_region (loop_preheader_edge (loop), exit, - bbs, n_bbs, NULL)) + entry = loop_preheader_edge (loop); + entry_count = entry->src->count; + body_count = exit->dest->count; + + if (!tree_duplicate_sese_region (entry, exit, bbs, n_bbs, copied_bbs)) { fprintf (dump_file, "Duplication failed.\n"); continue; } + /* Fix profiling info. Scaling is done in gcov_type arithmetic to + avoid losing information; this is slow, but is done at most + once per loop. We special case 0 to avoid division by 0; + probably other special cases exist. */ + total_count = body_count + entry_count; + if (total_count == 0LL) + { + scale_bbs_frequencies_int (bbs, n_bbs, 0, 1); + scale_bbs_frequencies_int (copied_bbs, n_bbs, 0, 1); + } + else + { + scale_bbs_frequencies_gcov_type (bbs, n_bbs, body_count, total_count); + scale_bbs_frequencies_gcov_type (copied_bbs, n_bbs, entry_count, + total_count); + } + /* Ensure that the latch and the preheader is simple (we know that they are not now, since there was the loop exit condition. */ loop_split_edge_with (loop_preheader_edge (loop), NULL); @@ -210,6 +235,7 @@ copy_loop_headers (void) } free (bbs); + free (copied_bbs); #ifdef ENABLE_CHECKING verify_loop_closed_ssa (); |