diff options
author | Jan Hubicka <jh@suse.cz> | 2005-03-18 21:15:06 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2005-03-18 20:15:06 +0000 |
commit | 33156717fa04cfb12d1b2c70ba1bdcd236e5a6b9 (patch) | |
tree | c8155205eea9acda3648c08b1f00c2d20be9270e /gcc | |
parent | 76ef0a0d97acb099fe476a8394704c6db73a4109 (diff) | |
download | gcc-33156717fa04cfb12d1b2c70ba1bdcd236e5a6b9.zip gcc-33156717fa04cfb12d1b2c70ba1bdcd236e5a6b9.tar.gz gcc-33156717fa04cfb12d1b2c70ba1bdcd236e5a6b9.tar.bz2 |
basic-block.h (scale_bbs_frequencies_int, [...]): Declare.
* 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.
Co-Authored-By: Dale Johannesen <dalej@apple.com>
From-SVN: r96700
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/basic-block.h | 3 | ||||
-rw-r--r-- | gcc/cfg.c | 43 | ||||
-rw-r--r-- | gcc/cfgloopmanip.c | 25 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-ch.c | 34 |
5 files changed, 91 insertions, 28 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6540e9d..73d0409 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2005-03-18 Jan Hubicka <jh@suse.cz> + Dale Johannesen <dalej@apple.com> + + * 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. + 2005-03-18 Kazu Hirata <kazu@cs.umass.edu> * config/m32r/m32r-protos.h: Remove the prototypes for diff --git a/gcc/basic-block.h b/gcc/basic-block.h index 45c511a..a767c6b 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -468,6 +468,9 @@ extern void dump_edge_info (FILE *, edge, int); extern void brief_dump_cfg (FILE *); extern void clear_edges (void); extern rtx first_insn_after_basic_block_note (basic_block); +extern void scale_bbs_frequencies_int (basic_block *, int, int, int); +extern void scale_bbs_frequencies_gcov_type (basic_block *, int, gcov_type, + gcov_type); /* Structure to group all of the information to process IF-THEN and IF-THEN-ELSE blocks for the conditional execution support. This @@ -96,6 +96,8 @@ static void free_edge (edge); /* Indicate the presence of the profile. */ enum profile_status profile_status; +#define RDIV(X,Y) (((X) + (Y) / 2) / (Y)) + /* Called once at initialization time. */ void @@ -933,10 +935,10 @@ update_bb_profile_for_threading (basic_block bb, int edge_frequency, } else if (prob != REG_BR_PROB_BASE) { - int scale = REG_BR_PROB_BASE / prob; + int scale = 65536 * REG_BR_PROB_BASE / prob; FOR_EACH_EDGE (c, ei, bb->succs) - c->probability *= scale; + c->probability *= scale / 65536; } if (bb != taken_edge->src) @@ -945,3 +947,40 @@ update_bb_profile_for_threading (basic_block bb, int edge_frequency, if (taken_edge->count < 0) taken_edge->count = 0; } + +/* Multiply all frequencies of basic blocks in array BBS of length NBBS + by NUM/DEN, in int arithmetic. May lose some accuracy. */ +void +scale_bbs_frequencies_int (basic_block *bbs, int nbbs, int num, int den) +{ + int i; + edge e; + for (i = 0; i < nbbs; i++) + { + edge_iterator ei; + bbs[i]->frequency = (bbs[i]->frequency * num) / den; + bbs[i]->count = RDIV (bbs[i]->count * num, den); + FOR_EACH_EDGE (e, ei, bbs[i]->succs) + e->count = (e->count * num) /den; + } +} + +/* Multiply all frequencies of basic blocks in array BBS of length NBBS + by NUM/DEN, in gcov_type arithmetic. More accurate than previous + function but considerably slower. */ +void +scale_bbs_frequencies_gcov_type (basic_block *bbs, int nbbs, gcov_type num, + gcov_type den) +{ + int i; + edge e; + + for (i = 0; i < nbbs; i++) + { + edge_iterator ei; + bbs[i]->frequency = (bbs[i]->frequency * num) / den; + bbs[i]->count = RDIV (bbs[i]->count * num, den); + FOR_EACH_EDGE (e, ei, bbs[i]->succs) + e->count = (e->count * num) /den; + } +} diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c index bd55788..1476906 100644 --- a/gcc/cfgloopmanip.c +++ b/gcc/cfgloopmanip.c @@ -45,7 +45,6 @@ static bool fix_bb_placement (struct loops *, basic_block); static void fix_bb_placements (struct loops *, basic_block); static void place_new_loop (struct loops *, struct loop *); static void scale_loop_frequencies (struct loop *, int, int); -static void scale_bbs_frequencies (basic_block *, int, int, int); static basic_block create_preheader (struct loop *, int); static void fix_irreducible_loops (basic_block); static void unloop (struct loops *, struct loop *); @@ -450,24 +449,6 @@ add_loop (struct loops *loops, struct loop *loop) free (bbs); } -/* Multiply all frequencies of basic blocks in array BBS of length NBBS - by NUM/DEN. */ -static void -scale_bbs_frequencies (basic_block *bbs, int nbbs, int num, int den) -{ - int i; - edge e; - - for (i = 0; i < nbbs; i++) - { - edge_iterator ei; - bbs[i]->frequency = (bbs[i]->frequency * num) / den; - bbs[i]->count = RDIV (bbs[i]->count * num, den); - FOR_EACH_EDGE (e, ei, bbs[i]->succs) - e->count = (e->count * num) /den; - } -} - /* Multiply all frequencies in LOOP by NUM/DEN. */ static void scale_loop_frequencies (struct loop *loop, int num, int den) @@ -475,7 +456,7 @@ scale_loop_frequencies (struct loop *loop, int num, int den) basic_block *bbs; bbs = get_loop_body (loop); - scale_bbs_frequencies (bbs, loop->num_nodes, num, den); + scale_bbs_frequencies_int (bbs, loop->num_nodes, num, den); free (bbs); } @@ -1059,7 +1040,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops, /* Set counts and frequencies. */ if (flags & DLTHE_FLAG_UPDATE_FREQ) { - scale_bbs_frequencies (new_bbs, n, scale_act, REG_BR_PROB_BASE); + scale_bbs_frequencies_int (new_bbs, n, scale_act, REG_BR_PROB_BASE); scale_act = RDIV (scale_act * scale_step[j], REG_BR_PROB_BASE); } } @@ -1071,7 +1052,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops, set_immediate_dominator (CDI_DOMINATORS, e->dest, e->src); if (flags & DLTHE_FLAG_UPDATE_FREQ) { - scale_bbs_frequencies (bbs, n, scale_main, REG_BR_PROB_BASE); + scale_bbs_frequencies_int (bbs, n, scale_main, REG_BR_PROB_BASE); free (scale_step); } diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c index 6d12271..fb5f7f6 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 (); |