aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-tailcall.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2005-07-27 09:40:25 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2005-07-27 07:40:25 +0000
commit2350455936313427a68eb1e0245a5e49d5ea8165 (patch)
tree27bc6922d5fcba18b1774d3f3530db164e793e4e /gcc/tree-tailcall.c
parent57a737092259093219f2f5bb95e3f70151a8f1dc (diff)
downloadgcc-2350455936313427a68eb1e0245a5e49d5ea8165.zip
gcc-2350455936313427a68eb1e0245a5e49d5ea8165.tar.gz
gcc-2350455936313427a68eb1e0245a5e49d5ea8165.tar.bz2
tree-tailcall.c (decrease_profile): New function.
* tree-tailcall.c (decrease_profile): New function. (eliminate_tail_call): Use it. * inliner-1.c: Add cleanup of dumps. * val-prof-*.c: Likewise. * update-tailcall.c: New. From-SVN: r102416
Diffstat (limited to 'gcc/tree-tailcall.c')
-rw-r--r--gcc/tree-tailcall.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index 3a40a61..3c7518d 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -668,6 +668,29 @@ adjust_return_value (basic_block bb, tree m, tree a)
update_stmt (ret_stmt);
}
+/* Subtract COUNT and FREQUENCY from the basic block and it's
+ outgoing edge. */
+static void
+decrease_profile (basic_block bb, gcov_type count, int frequency)
+{
+ edge e;
+ bb->count -= count;
+ if (bb->count < 0)
+ bb->count = 0;
+ bb->frequency -= frequency;
+ if (bb->frequency < 0)
+ bb->frequency = 0;
+ if (!single_succ_p (bb))
+ {
+ gcc_assert (!EDGE_COUNT (bb->succs));
+ return;
+ }
+ e = single_succ_edge (bb);
+ e->count -= count;
+ if (e->count < 0)
+ e->count = 0;
+}
+
/* Eliminates tail call described by T. TMP_VARS is a list of
temporary variables used to copy the function arguments. */
@@ -717,6 +740,13 @@ eliminate_tail_call (struct tailcall *t)
release_defs (t);
}
+ /* Number of executions of function has reduced by the tailcall. */
+ e = single_succ_edge (t->call_block);
+ decrease_profile (EXIT_BLOCK_PTR, e->count, EDGE_FREQUENCY (e));
+ decrease_profile (ENTRY_BLOCK_PTR, e->count, EDGE_FREQUENCY (e));
+ if (e->dest != EXIT_BLOCK_PTR)
+ decrease_profile (e->dest, e->count, EDGE_FREQUENCY (e));
+
/* Replace the call by a jump to the start of function. */
e = redirect_edge_and_branch (single_succ_edge (t->call_block), first);
gcc_assert (e);