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]

crossjumping speedups


Hi,
this patch restructure the tests made by crossjumping somewhat to
cut down compilation time on Roman's testcase from 48% to 6%.  Now
it is about 3 times faster than original jump.c implementation.

Fri Jul 20 20:55:04 CEST 2001  Jan Hubicka  <jh@suse.cz>
	* (outgoing_edges_match): Cheap tests first.
	(try_crossjump_edge): Kill tests for BB to be non-forwarders.
	(try_crossjump_bb): Ensure BB is not forwarder; Avoid duplicated
	work.

Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.430
diff -c -3 -p -r1.430 flow.c
*** flow.c	2001/07/18 17:11:10	1.430
--- flow.c	2001/07/20 18:53:37
*************** outgoing_edges_match (bb1, bb2)
*** 3366,3371 ****
--- 3366,3378 ----
        if (forwarder_block_p (f2->dest))
  	f2 = f2->dest->succ;
  
+       if (f1->dest == f2->dest && b1->dest == b2->dest)
+ 	reverse = false;
+       else if (f1->dest == b2->dest && b1->dest == f2->dest)
+ 	reverse = true;
+       else
+ 	return false;
+ 
        /* To simplify use of this function, return false if there are
  	 unneeded forwarder blocks.  These will get eliminated later
  	 during cleanup_cfg.  */
*************** outgoing_edges_match (bb1, bb2)
*** 3375,3387 ****
  	  || forwarder_block_p (b2->dest))
  	return false;
  
-       if (f1->dest == f2->dest && b1->dest == b2->dest)
- 	reverse = false;
-       else if (f1->dest == b2->dest && b1->dest == f2->dest)
- 	reverse = true;
-       else
- 	return false;
- 
        set1 = pc_set (bb1->end);
        set2 = pc_set (bb2->end);
        if ((XEXP (SET_SRC (set1), 1) == pc_rtx)
--- 3382,3387 ----
*************** try_crossjump_to_edge (mode, e1, e2)
*** 3466,3471 ****
--- 3466,3472 ----
    if (e1->src->pred && !e1->src->pred->pred_next
        && forwarder_block_p (e1->src))
      e1 = e1->src->pred;
+ 
    if (e2->src->pred && !e2->src->pred->pred_next
        && forwarder_block_p (e2->src))
      e2 = e2->src->pred;
*************** try_crossjump_to_edge (mode, e1, e2)
*** 3475,3488 ****
    if (e1->src == e2->src)
      return false;
  
!   /* Seeing more than 1 forwarder blocks would confuse us later...  */
!   if (forwarder_block_p (e1->dest)
!       && forwarder_block_p (e1->dest->succ->dest))
!     return false;
!   if (forwarder_block_p (e2->dest)
!       && forwarder_block_p (e2->dest->succ->dest))
!     return false;
!   /* ... similary as seeing dead code...  */
    if (!e1->src->pred || !e2->src->pred)
      return false;
    /* ...similary non-jump edges.  */
--- 3476,3482 ----
    if (e1->src == e2->src)
      return false;
  
!   /* Seeing dead code would confuse us...  */
    if (!e1->src->pred || !e2->src->pred)
      return false;
    /* ...similary non-jump edges.  */
*************** try_crossjump_bb (mode, bb)
*** 3608,3613 ****
--- 3602,3613 ----
    if (!bb->pred || !bb->pred->pred_next)
      return false;
  
+   /* The probability updating code in try_crossjump_to_edge expect join
+      block to not be forwarder.  As try_crossjump_to_edge is able to
+      get around forwarders, the crossjumping will happen later.  */
+   if (forwarder_block_p (bb))
+     return false;
+ 
    /* It is always cheapest to jump into fallthru edge.  */
    for (fallthru = bb->pred; fallthru; fallthru = fallthru->pred_next)
      if (fallthru->flags & EDGE_FALLTHRU)
*************** try_crossjump_bb (mode, bb)
*** 3616,3623 ****
    for (e = bb->pred; e; e = nexte)
      {
        nexte = e->pred_next;
!       /* First of all prioritize the fallthru edge, as the cheapest.  */
        if (e != fallthru && fallthru
  	  && try_crossjump_to_edge (mode, e, fallthru))
  	changed = true, nexte = bb->pred;
        else
--- 3616,3629 ----
    for (e = bb->pred; e; e = nexte)
      {
        nexte = e->pred_next;
! 
!       /* First of all prioritize the fallthru edge, as the cheapest.
!         
!          Avoid duplicated work by ensuring that at least one of edges
!          is the first outgoing edge.  This way we try each combination
!          maximally twice, instead of N ougoing edges ^ 2.  */
        if (e != fallthru && fallthru
+ 	  && (e->src->succ == e || fallthru->src->succ == fallthru)
  	  && try_crossjump_to_edge (mode, e, fallthru))
  	changed = true, nexte = bb->pred;
        else
*************** try_crossjump_bb (mode, bb)
*** 3628,3634 ****
  	for (e2 = bb->pred; e2 != e; e2 = nexte2)
  	  {
  	    nexte2 = e2->pred_next;
! 	    if (e2 != fallthru && try_crossjump_to_edge (mode, e, e2))
  	      {
  		changed = true;
  		nexte = bb->pred;
--- 3634,3642 ----
  	for (e2 = bb->pred; e2 != e; e2 = nexte2)
  	  {
  	    nexte2 = e2->pred_next;
! 	    if (e2 != fallthru
! 	        && (e->src->succ == e || e2->src->succ == e2)
! 	        && try_crossjump_to_edge (mode, e, e2))
  	      {
  		changed = true;
  		nexte = bb->pred;


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