mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-28 13:34:59 +08:00
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
This commit is contained in:
parent
57a7370922
commit
2350455936
@ -1,5 +1,8 @@
|
||||
2005-07-27 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* tree-tailcall.c (decrease_profile): New function.
|
||||
(eliminate_tail_call): Use it.
|
||||
|
||||
* cgraphunit.c (cgraph_function_and_variable_visibility): Set
|
||||
visibility flags correctly in whole program mode.
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2005-07-27 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* inliner-1.c: Add cleanup of dumps.
|
||||
* val-prof-*.c: Likewise.
|
||||
* update-tailcall.c: New.
|
||||
|
||||
2005-07-26 Diego Novillo <dnovillo@redhat.com>
|
||||
|
||||
PR 22591
|
||||
|
@ -35,3 +35,4 @@ main ()
|
||||
declaration or other apperances of the string in dump. */
|
||||
/* { dg-final-use { scan-tree-dump "cold_function ..;" "optimized"} } */
|
||||
/* { dg-final-use { scan-tree-dump-not "hot_function ..;" "optimized"} } */
|
||||
/* { dg-final-use { cleanup-tree-dump "optimized" } } */
|
||||
|
20
gcc/testsuite/gcc.dg/tree-prof/update-tailcall.c
Normal file
20
gcc/testsuite/gcc.dg/tree-prof/update-tailcall.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* { dg-options "-O2 -fdump-tree-tailcall -fdump-tree-optimized" } */
|
||||
__attribute__ ((noinline))
|
||||
int factorial(int x)
|
||||
{
|
||||
if (x == 1)
|
||||
return 1;
|
||||
else
|
||||
return x*factorial(--x);
|
||||
}
|
||||
int gbl;
|
||||
int
|
||||
main()
|
||||
{
|
||||
gbl = factorial(100);
|
||||
return 0;
|
||||
}
|
||||
/* { dg-final-use { scan-tree-dump-not "Invalid sum" "tailc"} } */
|
||||
/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
|
||||
/* { dg-final-use { cleanup-tree-dump "tailc" } } */
|
||||
/* { dg-final-use { cleanup-tree-dump "optimized" } } */
|
@ -18,3 +18,5 @@ main ()
|
||||
/* { dg-final-use { scan-tree-dump "Div.mod by constant n=257 transformation on insn" "tree_profile"} } */
|
||||
/* { dg-final-use { scan-tree-dump "if \\(n != 257\\)" "optimized"} } */
|
||||
/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
|
||||
/* { dg-final-use { cleanup-tree-dump "optimized" } } */
|
||||
/* { dg-final-use { cleanup-tree-dump "tree_profile" } } */
|
||||
|
@ -28,3 +28,5 @@ main ()
|
||||
didn't get optimized out. */
|
||||
/* { dg-final-use { scan-tree-dump "n \\+ \\-1" "optimized"} } */
|
||||
/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
|
||||
/* { dg-final-use { cleanup-tree-dump "optimized" } } */
|
||||
/* { dg-final-use { cleanup-tree-dump "tree_profile" } } */
|
||||
|
@ -28,3 +28,5 @@ main ()
|
||||
didn't get optimized out. */
|
||||
/* { dg-final-use { scan-tree-dump "if \\(n \\>" "optimized"} } */
|
||||
/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
|
||||
/* { dg-final-use { cleanup-tree-dump "optimized" } } */
|
||||
/* { dg-final-use { cleanup-tree-dump "tree_profile" } } */
|
||||
|
@ -28,3 +28,5 @@ main ()
|
||||
didn't get optimized out. */
|
||||
/* { dg-final-use { scan-tree-dump "if \\(n \\>" "optimized"} } */
|
||||
/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
|
||||
/* { dg-final-use { cleanup-tree-dump "optimized" } } */
|
||||
/* { dg-final-use { cleanup-tree-dump "tree_profile" } } */
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user