aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2010-06-29 16:14:15 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2010-06-29 14:14:15 +0000
commitb35366ce42d0cc1218679337be0a779c20af35e0 (patch)
treea5ef0708be39861c165f5c5612b671234a8fd8de /gcc/tree-inline.c
parent50b56694bb665f06ad0a327498bebe45e0bd3d0d (diff)
downloadgcc-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.c46
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);