diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-28 07:41:29 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-07-28 07:41:29 +0000 |
commit | f57c928a7d391b70d3ec7a84b95d74d1d5297c58 (patch) | |
tree | fe00ab26a84db5f867ad0e76607a799b23f5a320 /gcc/cfg.c | |
parent | 4d053acaffc4a77e00459aee81e951b34a4faeb3 (diff) | |
download | gcc-f57c928a7d391b70d3ec7a84b95d74d1d5297c58.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@102466 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfg.c')
-rw-r--r-- | gcc/cfg.c | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/gcc/cfg.c b/gcc/cfg.c index e6af6cfbaff..96441326ac6 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 |