X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcfg.c;h=c46ac0b88eeb1b06d9098f63e7befca5dc65dbba;hb=839904a0e3a1859cdfeb5ff23e5263c332f347fa;hp=4a3e6ad5cd927e97d945ce762776881cc6dabc1e;hpb=67ce556b47830dd825524e8370969b814c355216;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cfg.c b/gcc/cfg.c index 4a3e6ad5cd9..c46ac0b88ee 100644 --- a/gcc/cfg.c +++ b/gcc/cfg.c @@ -136,16 +136,6 @@ alloc_block (void) return bb; } -/* Initialize rbi (the structure containing data used by basic block - duplication and reordering) for the given basic block. */ - -void -initialize_bb_rbi (basic_block bb) -{ - gcc_assert (!bb->rbi); - bb->rbi = ggc_alloc_cleared (sizeof (struct reorder_block_def)); -} - /* Link block B to chain after AFTER. */ void link_block (basic_block b, basic_block after) @@ -860,7 +850,12 @@ update_bb_profile_for_threading (basic_block bb, int edge_frequency, bb->count -= count; if (bb->count < 0) - bb->count = 0; + { + if (dump_file) + fprintf (dump_file, "bb %i count became negative after threading", + bb->index); + bb->count = 0; + } /* Compute the probability of TAKEN_EDGE being reached via threaded edge. Watch for overflows. */ @@ -898,16 +893,25 @@ 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 *= scale / 65536; + { + c->probability = RDIV (c->probability * scale, 65536); + if (c->probability > REG_BR_PROB_BASE) + c->probability = REG_BR_PROB_BASE; + } } gcc_assert (bb == taken_edge->src); taken_edge->count -= count; if (taken_edge->count < 0) - taken_edge->count = 0; + { + if (dump_file) + fprintf (dump_file, "edge %i->%i count became negative after threading", + taken_edge->src->index, taken_edge->dest->index); + taken_edge->count = 0; + } } /* Multiply all frequencies of basic blocks in array BBS of length NBBS @@ -917,16 +921,27 @@ scale_bbs_frequencies_int (basic_block *bbs, int nbbs, int num, int den) { int i; edge e; + if (num < 0) + num = 0; + if (num > den) + return; + /* Assume that the users are producing the fraction from frequencies + that never grow far enough 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. */ @@ -936,18 +951,41 @@ 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); + } } -/* Datastructures used to maintain mapping between basic blocks and copies. */ +/* Data structures used to maintain mapping between basic blocks and + copies. */ static htab_t bb_original; static htab_t bb_copy; static alloc_pool original_copy_bb_pool; @@ -979,7 +1017,8 @@ bb_copy_original_eq (const void *p, const void *q) return data->index1 == data2->index1; } -/* Initialize the datstructures to maintain mapping between blocks and it's copies. */ +/* Initialize the data structures to maintain mapping between blocks + and its copies. */ void initialize_original_copy_tables (void) { @@ -992,7 +1031,8 @@ initialize_original_copy_tables (void) bb_copy = htab_create (10, bb_copy_original_hash, bb_copy_original_eq, NULL); } -/* Free the datstructures to maintain mapping between blocks and it's copies. */ +/* Free the data structures to maintain mapping between blocks and + its copies. */ void free_original_copy_tables (void) { @@ -1005,8 +1045,8 @@ free_original_copy_tables (void) original_copy_bb_pool = NULL; } -/* Set original for basic block. Do nothing when datstructures are not - intialized so passes not needing this don't need to care. */ +/* Set original for basic block. Do nothing when data structures are not + initialized so passes not needing this don't need to care. */ void set_bb_original (basic_block bb, basic_block original) { @@ -1047,8 +1087,8 @@ get_bb_original (basic_block bb) return NULL; } -/* Set copy for basic block. Do nothing when datstructures are not - intialized so passes not needing this don't need to care. */ +/* Set copy for basic block. Do nothing when data structures are not + initialized so passes not needing this don't need to care. */ void set_bb_copy (basic_block bb, basic_block copy) {