This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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 ();


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]