This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix profile updating in tailcall
- From: Jan Hubicka <jh at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 27 Jul 2005 09:38:42 +0200
- Subject: Fix profile updating in tailcall
Hi,
tailcall reduces number of invocations of function but forgets to update
profile. Interestingly this causes code estimating number of iterations
to always return 1 iteration that results in newly formed loop beeing
peeled instead of unrolled and cause us to lose relative to ICC on very
important ackerman function benchmark ;). Fixed thus. I've also took
oppurtunity to fix cleanup of dump files as pointed out by Janis ages
ago.
Bootstrapped/regtested i686-pc-gnu-linux, comitted.
Honza
2005-07-27 Jan Hubicka <jh@suse.cz>
* 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.
Index: tree-tailcall.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-tailcall.c,v
retrieving revision 2.45
diff -c -3 -p -r2.45 tree-tailcall.c
*** tree-tailcall.c 13 Jul 2005 22:35:28 -0000 2.45
--- tree-tailcall.c 27 Jul 2005 07:27:14 -0000
*************** adjust_return_value (basic_block bb, tre
*** 668,673 ****
--- 668,696 ----
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. */
*************** eliminate_tail_call (struct tailcall *t)
*** 717,722 ****
--- 740,752 ----
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);
Index: testsuite/gcc.dg/tree-prof/inliner-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/tree-prof/inliner-1.c,v
retrieving revision 1.1
diff -c -3 -p -r1.1 inliner-1.c
*** testsuite/gcc.dg/tree-prof/inliner-1.c 25 May 2005 12:34:01 -0000 1.1
--- testsuite/gcc.dg/tree-prof/inliner-1.c 27 Jul 2005 07:27:19 -0000
*************** main ()
*** 35,37 ****
--- 35,38 ----
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" } } */
Index: testsuite/gcc.dg/tree-prof/update-tailcall.c
===================================================================
RCS file: testsuite/gcc.dg/tree-prof/update-tailcall.c
diff -N testsuite/gcc.dg/tree-prof/update-tailcall.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/tree-prof/update-tailcall.c 27 Jul 2005 07:27:19 -0000
***************
*** 0 ****
--- 1,18 ----
+ /* { dg-options "-O2 -fdump-tree-tailcall" } */
+ __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 { cleanup-tree-dump "tailc" } } */
Index: testsuite/gcc.dg/tree-prof/val-prof-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c,v
retrieving revision 1.1
diff -c -3 -p -r1.1 val-prof-1.c
*** testsuite/gcc.dg/tree-prof/val-prof-1.c 28 May 2005 18:03:56 -0000 1.1
--- testsuite/gcc.dg/tree-prof/val-prof-1.c 27 Jul 2005 07:27:19 -0000
*************** main ()
*** 18,20 ****
--- 18,22 ----
/* { 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" } } */
Index: testsuite/gcc.dg/tree-prof/val-prof-2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c,v
retrieving revision 1.1
diff -c -3 -p -r1.1 val-prof-2.c
*** testsuite/gcc.dg/tree-prof/val-prof-2.c 28 May 2005 18:03:56 -0000 1.1
--- testsuite/gcc.dg/tree-prof/val-prof-2.c 27 Jul 2005 07:27:19 -0000
*************** main ()
*** 28,30 ****
--- 28,32 ----
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" } } */
Index: testsuite/gcc.dg/tree-prof/val-prof-3.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c,v
retrieving revision 1.1
diff -c -3 -p -r1.1 val-prof-3.c
*** testsuite/gcc.dg/tree-prof/val-prof-3.c 28 May 2005 18:03:56 -0000 1.1
--- testsuite/gcc.dg/tree-prof/val-prof-3.c 27 Jul 2005 07:27:19 -0000
*************** main ()
*** 28,30 ****
--- 28,32 ----
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" } } */
Index: testsuite/gcc.dg/tree-prof/val-prof-4.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c,v
retrieving revision 1.1
diff -c -3 -p -r1.1 val-prof-4.c
*** testsuite/gcc.dg/tree-prof/val-prof-4.c 28 May 2005 18:03:56 -0000 1.1
--- testsuite/gcc.dg/tree-prof/val-prof-4.c 27 Jul 2005 07:27:19 -0000
*************** main ()
*** 28,30 ****
--- 28,32 ----
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" } } */