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 | |
parent | 2c191cc3f2f5ebcb6054b344f1ae08cfcd8fe516 (diff) | |
download | linaro-gcc-4d6b11ab420f373787b369905fe1271927ae671c.tar.gz linaro-gcc-4d6b11ab420f373787b369905fe1271927ae671c.tar.bz2 linaro-gcc-4d6b11ab420f373787b369905fe1271927ae671c.zip |
* 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')
-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 6540e9da330..73d04098535 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 45c511a1975..a767c6b7fa1 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 diff --git a/gcc/cfg.c b/gcc/cfg.c index 03f1ee1f9d2..c0e38f2910f 100644 --- a/gcc/cfg.c +++ b/gcc/cfg.c @@ -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 bd55788483d..14769067279 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 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 (); |