diff options
author | Jan Hubicka <jh@suse.cz> | 2010-06-29 16:14:15 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2010-06-29 14:14:15 +0000 |
commit | b35366ce42d0cc1218679337be0a779c20af35e0 (patch) | |
tree | a5ef0708be39861c165f5c5612b671234a8fd8de /gcc/tree-inline.c | |
parent | 50b56694bb665f06ad0a327498bebe45e0bd3d0d (diff) | |
download | gcc-b35366ce42d0cc1218679337be0a779c20af35e0.zip gcc-b35366ce42d0cc1218679337be0a779c20af35e0.tar.gz gcc-b35366ce42d0cc1218679337be0a779c20af35e0.tar.bz2 |
predict.c (propagate_freq): Clear EXIT_BLOCK_PTR frequency if it is unreachable.
* predict.c (propagate_freq): Clear EXIT_BLOCK_PTR frequency if it is
unreachable.
(rebuild_frequencies): New function.
* predict.h (rebuild_frequencies): Declare.
* tree-inline.c (copy_cfg_body): Compute properly count & frequency of
entry block and edge reaching new_entry.
(tree_function_versioning): When doing partial cloning, rebuild frequencies
when done.
* passes.c (execute_function_todo): Use rebild_frequencies.
From-SVN: r161536
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r-- | gcc/tree-inline.c | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 2604c6b..3ef1cc3 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -2159,6 +2159,8 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, bool need_debug_cleanup = false; gcov_type count_scale; int last; + int incomming_frequency = 0; + gcov_type incomming_count = 0; if (ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count) count_scale = (REG_BR_PROB_BASE * count @@ -2169,6 +2171,28 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, /* Register specific tree functions. */ gimple_register_cfg_hooks (); + /* If we are inlining just region of the function, make sure to connect new entry + to ENTRY_BLOCK_PTR. Since new entry can be part of loop, we must compute + frequency and probability of ENTRY_BLOCK_PTR based on the frequencies and + probabilities of edges incomming from nonduplicated region. */ + if (new_entry) + { + edge e; + edge_iterator ei; + + FOR_EACH_EDGE (e, ei, new_entry->preds) + if (!e->src->aux) + { + incomming_frequency += EDGE_FREQUENCY (e); + incomming_count += e->count; + } + incomming_count = incomming_count * count_scale / REG_BR_PROB_BASE; + incomming_frequency + = incomming_frequency * frequency_scale / REG_BR_PROB_BASE; + ENTRY_BLOCK_PTR->count = incomming_count; + ENTRY_BLOCK_PTR->frequency = incomming_frequency; + } + /* Must have a CFG here at this point. */ gcc_assert (ENTRY_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (callee_fndecl))); @@ -2204,10 +2228,9 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, if (new_entry) { - edge e; - e = make_edge (entry_block_map, (basic_block)new_entry->aux, EDGE_FALLTHRU); + edge e = make_edge (entry_block_map, (basic_block)new_entry->aux, EDGE_FALLTHRU); e->probability = REG_BR_PROB_BASE; - e->count = entry_block_map->count; + e->count = incomming_count; } if (gimple_in_ssa_p (cfun)) @@ -5206,6 +5229,23 @@ tree_function_versioning (tree old_decl, tree new_decl, if (id.dst_node->analyzed) cgraph_rebuild_references (); update_ssa (TODO_update_ssa); + + /* After partial cloning we need to rescale frequencies, so they are + within proper range in the cloned function. */ + if (new_entry) + { + struct cgraph_edge *e; + rebuild_frequencies (); + + new_version_node->count = ENTRY_BLOCK_PTR->count; + for (e = new_version_node->callees; e; e = e->next_callee) + { + basic_block bb = gimple_bb (e->call_stmt); + e->frequency = compute_call_stmt_bb_frequency (current_function_decl, bb); + e->count = bb->count; + } + } + free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS); |