This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] tree-cfg.c: Speed up cleanup_tree_cfg().
- From: Kazu Hirata <kazu at cs dot umass dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 01 Oct 2004 09:03:04 -0400 (EDT)
- Subject: [patch] tree-cfg.c: Speed up cleanup_tree_cfg().
Hi,
Attached is a patch to speed up cleanup_tree_cfg().
Consider the loop in cleanup_tree_cfg().
while (something_changed)
{
something_changed = cleanup_control_flow ();
something_changed |= delete_unreachable_blocks ();
something_changed |= thread_jumps ();
retval |= something_changed;
}
Note that cleanup_control_flow() looks at the condition portion of
each COND_EXPR and SWITCH_EXPR. Neither delete_unreachable_blocks()
or thread_jumps() modifies the condition portion of any COND_EXPR or
SWITCH_EXPR, so neither of them affects the result of
cleanup_control_flow(). Therefore, we can pull it out of the loop.
Here is the timing for 10 runs of "cc1 -O2 -o /dev/null fold-const.i".
original patched patched*
real: 183.800 183.358 (0.240% down) 182.447 (0.736% down)
user: 181.106 180.796 (0.171% down) 179.965 (0.630% down)
"patched*" is the patched GCC without the gcc_assert newly added in
the patch.
I am wondering if we actually need the gcc_assert(). I'll leave it up
to you to decide whether we should keep it.
Tested on i686-pc-linux-gnu. OK to apply?
Kazu Hirata
2004-10-01 Kazu Hirata <kazu@cs.umass.edu>
* tree-cfg.c (cleanup_tree_cfg): Pull a call to
cleanup_control_flow() out of the while loop.
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-cfg.c,v
retrieving revision 2.60
diff -c -r2.60 tree-cfg.c
*** tree-cfg.c 30 Sep 2004 18:27:25 -0000 2.60
--- tree-cfg.c 1 Oct 2004 01:02:14 -0000
***************
*** 717,732 ****
timevar_push (TV_TREE_CLEANUP_CFG);
! /* These three transformations can cascade, so we iterate on them until
nothing changes. */
while (something_changed)
{
! something_changed = cleanup_control_flow ();
! something_changed |= delete_unreachable_blocks ();
something_changed |= thread_jumps ();
retval |= something_changed;
}
/* Merging the blocks creates no new opportunities for the other
optimizations, so do it here. */
merge_seq_blocks ();
--- 717,738 ----
timevar_push (TV_TREE_CLEANUP_CFG);
! retval = cleanup_control_flow ();
!
! /* These two transformations can cascade, so we iterate on them until
nothing changes. */
while (something_changed)
{
! something_changed = delete_unreachable_blocks ();
something_changed |= thread_jumps ();
retval |= something_changed;
}
+ #ifdef ENABLE_CHECKING
+ if (retval)
+ gcc_assert (!cleanup_control_flow ());
+ #endif
+
/* Merging the blocks creates no new opportunities for the other
optimizations, so do it here. */
merge_seq_blocks ();