From 09bac500fc57a399ef7df847f29c21b956280306 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 28 Jul 2005 07:41:29 +0000 Subject: cfg.c (update_bb_profile_for_threading): Use RDIV. * cfg.c (update_bb_profile_for_threading): Use RDIV. (scale_bbs_frequencies_int): Likewise, assert for possible overflow. (scale_bbs_frequencies_gcov_type): Be more curefull about overflows and roundoff errors. * tree-cfg.c (tree_duplicate_sese_region): Use counts for updating profile when available. * update-loopch.c: New testcase. From-SVN: r102466 --- gcc/cfg.c | 53 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 12 deletions(-) (limited to 'gcc/cfg.c') diff --git a/gcc/cfg.c b/gcc/cfg.c index e6af6cf..9644132 100644 --- a/gcc/cfg.c +++ b/gcc/cfg.c @@ -893,11 +893,11 @@ update_bb_profile_for_threading (basic_block bb, int edge_frequency, } else if (prob != REG_BR_PROB_BASE) { - int scale = 65536 * REG_BR_PROB_BASE / prob; + int scale = RDIV (65536 * REG_BR_PROB_BASE, prob); FOR_EACH_EDGE (c, ei, bb->succs) { - c->probability = (c->probability * scale) / 65536; + c->probability = RDIV (c->probability * scale, 65536); if (c->probability > REG_BR_PROB_BASE) c->probability = REG_BR_PROB_BASE; } @@ -925,16 +925,23 @@ scale_bbs_frequencies_int (basic_block *bbs, int nbbs, int num, int den) num = 0; if (num > den) return; + /* Assume that the users are producing the fraction from frequencies + that never grow far enought to risk arithmetic overflow. */ + gcc_assert (num < 65536); for (i = 0; i < nbbs; i++) { edge_iterator ei; - bbs[i]->frequency = (bbs[i]->frequency * num) / den; + bbs[i]->frequency = RDIV (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; + e->count = RDIV (e->count * num, den); } } +/* numbers smaller than this value are safe to multiply without getting + 64bit overflow. */ +#define MAX_SAFE_MULTIPLIER (1 << (sizeof (HOST_WIDEST_INT) * 4 - 1)) + /* 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. */ @@ -944,15 +951,37 @@ scale_bbs_frequencies_gcov_type (basic_block *bbs, int nbbs, gcov_type num, { int i; edge e; + gcov_type fraction = RDIV (num * 65536, den); - 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; - } + gcc_assert (fraction >= 0); + + if (num < MAX_SAFE_MULTIPLIER) + for (i = 0; i < nbbs; i++) + { + edge_iterator ei; + bbs[i]->frequency = RDIV (bbs[i]->frequency * num, den); + if (bbs[i]->count <= MAX_SAFE_MULTIPLIER) + bbs[i]->count = RDIV (bbs[i]->count * num, den); + else + bbs[i]->count = RDIV (bbs[i]->count * fraction, 65536); + FOR_EACH_EDGE (e, ei, bbs[i]->succs) + if (bbs[i]->count <= MAX_SAFE_MULTIPLIER) + e->count = RDIV (e->count * num, den); + else + e->count = RDIV (e->count * fraction, 65536); + } + else + for (i = 0; i < nbbs; i++) + { + edge_iterator ei; + if (sizeof (gcov_type) > sizeof (int)) + bbs[i]->frequency = RDIV (bbs[i]->frequency * num, den); + else + bbs[i]->frequency = RDIV (bbs[i]->frequency * fraction, 65536); + bbs[i]->count = RDIV (bbs[i]->count * fraction, 65536); + FOR_EACH_EDGE (e, ei, bbs[i]->succs) + e->count = RDIV (e->count * fraction, 65536); + } } /* Data structures used to maintain mapping between basic blocks and -- cgit v1.1