summaryrefslogtreecommitdiff
path: root/gcc/tree-tailcall.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2017-11-17 18:44:41 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2017-11-17 17:44:41 +0000
commitdb16c1841a09f60bbdf2bb825e7e790a437f83c7 (patch)
tree0b8ddecbdf0968c20f67c16dec7dae40527dba93 /gcc/tree-tailcall.c
parent3860f31db1e1b155532fb96a3e703b6b9e780753 (diff)
tree-tailcall.c (eliminate_tail_call): Be more careful about not disturbin profile of entry block.
* tree-tailcall.c (eliminate_tail_call): Be more careful about not disturbin profile of entry block. From-SVN: r254887
Diffstat (limited to 'gcc/tree-tailcall.c')
-rw-r--r--gcc/tree-tailcall.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index 0e637147e8c..212519cdfd7 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -889,10 +889,18 @@ eliminate_tail_call (struct tailcall *t)
/* Number of executions of function has reduced by the tailcall. */
e = single_succ_edge (gsi_bb (t->call_gsi));
- decrease_profile (EXIT_BLOCK_PTR_FOR_FN (cfun), e->count ());
- decrease_profile (ENTRY_BLOCK_PTR_FOR_FN (cfun), e->count ());
+
+ profile_count count = e->count ();
+
+ /* When profile is inconsistent and the recursion edge is more frequent
+ than number of executions of functions, scale it down, so we do not end
+ up with 0 executions of entry block. */
+ if (count >= ENTRY_BLOCK_PTR_FOR_FN (cfun)->count)
+ count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.apply_scale (7, 8);
+ decrease_profile (EXIT_BLOCK_PTR_FOR_FN (cfun), count);
+ decrease_profile (ENTRY_BLOCK_PTR_FOR_FN (cfun), count);
if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
- decrease_profile (e->dest, e->count ());
+ decrease_profile (e->dest, count);
/* Replace the call by a jump to the start of function. */
e = redirect_edge_and_branch (single_succ_edge (gsi_bb (t->call_gsi)),