aboutsummaryrefslogtreecommitdiff
path: root/gcc/predict.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2010-06-29 14:14:15 +0000
committerJan Hubicka <jh@suse.cz>2010-06-29 14:14:15 +0000
commitdf38c13cf6059ad4b7fca46da145ac877f67db45 (patch)
treea5ef0708be39861c165f5c5612b671234a8fd8de /gcc/predict.c
parent8b432002a5e6b5b419657abae9ce6490d92e92d5 (diff)
* 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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@161536 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/predict.c')
-rw-r--r--gcc/predict.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/gcc/predict.c b/gcc/predict.c
index 1bccd4d2c26..5d61140e4e6 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -1855,9 +1855,6 @@ propagate_freq (basic_block head, bitmap tovisit)
edge_iterator ei;
int count = 0;
- /* The outermost "loop" includes the exit block, which we can not
- look up via BASIC_BLOCK. Detect this and use EXIT_BLOCK_PTR
- directly. Do the same for the entry block. */
bb = BASIC_BLOCK (i);
FOR_EACH_EDGE (e, ei, bb->preds)
@@ -1872,6 +1869,9 @@ propagate_freq (basic_block head, bitmap tovisit)
e->src->index, bb->index);
}
BLOCK_INFO (bb)->npredecessors = count;
+ /* When function never returns, we will never process exit block. */
+ if (!count && bb == EXIT_BLOCK_PTR)
+ bb->count = bb->frequency = 0;
}
memcpy (&BLOCK_INFO (head)->frequency, &real_one, sizeof (real_one));
@@ -2282,3 +2282,27 @@ struct gimple_opt_pass pass_strip_predict_hints =
TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
}
};
+
+/* Rebuild function frequencies. Passes are in general expected to
+ maintain profile by hand, however in some cases this is not possible:
+ for example when inlining several functions with loops freuqencies might run
+ out of scale and thus needs to be recomputed. */
+
+void
+rebuild_frequencies (void)
+{
+ if (profile_status == PROFILE_GUESSED)
+ {
+ loop_optimizer_init (0);
+ add_noreturn_fake_exit_edges ();
+ mark_irreducible_loops ();
+ connect_infinite_loops_to_exit ();
+ estimate_bb_frequencies ();
+ remove_fake_exit_edges ();
+ loop_optimizer_finalize ();
+ }
+ else if (profile_status == PROFILE_READ)
+ counts_to_freqs ();
+ else
+ gcc_unreachable ();
+}