Crossjumping fix II

Jan Hubicka jh@suse.cz
Tue Dec 18 06:57:00 GMT 2001


> 	Three testcases failed on PowerPC with all optimization levels
> after your original original cfgcleanup.c patch.  This latest patch fixes
> one of the cases, but two others still fail:
> 
> 920428-2.c
> 920501-3.c (fixed)
> 920501-7.c
> 
> 	These also fail on the powerpc-sim tester, so you should have
> received email from the tester when these new regressions occurred and you
> have a simulator on which to test fixes.  Are you addressing these other
> regressions from your patch?

Hi,
this patch should fix the crossjumping problems.  It replaces Richard's patch
by, I hope, proper sollution that does not disable crossjumping over
simplejumps.

It allows insns to match even when number of fake edges does not - this is
important for calls being last in the function. Finaly it requires conditionals
to not have side effect, as may happen on PA.

For sure I've also modified flow_find_cross_jump to not die if the conditionals
not match.  This may happen with non-simplejump but elliminable jump not
seen by the proper simplifier yet.

Hope it fixes all the problems.  I've verified the PPC testcases.

Honza

Tue Dec 18 15:37:51 CET 2001  Jan Hubicka  <jh@suse.cz>
	* cfgcleanup.c (flow_find_cross_jump): Avoid incrementing of ninsns
	if one of block does not contain jump.
	(outgoing_edge_math): Revert last path; require edges to be noncomplex
	nonfake to match single exit edge; require conditional jumps to not
	have side effect.

Index: cfgcleanup.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cfgcleanup.c,v
retrieving revision 1.26
diff -c -3 -p -r1.26 cfgcleanup.c
*** cfgcleanup.c	2001/12/17 18:21:36	1.26
--- cfgcleanup.c	2001/12/18 14:37:40
*************** flow_find_cross_jump (mode, bb1, bb2, f1
*** 855,863 ****
        || (returnjump_p (i1) && !side_effects_p (PATTERN (i1))))
      {
        last1 = i1;
-       /* Count everything except for unconditional jump as insn.  */
-       if (!simplejump_p (i1) && !returnjump_p (i1))
- 	ninsns++;
        i1 = PREV_INSN (i1);
      }
    i2 = bb2->end;
--- 855,860 ----
*************** flow_find_cross_jump (mode, bb1, bb2, f1
*** 865,870 ****
--- 862,870 ----
        || (returnjump_p (i2) && !side_effects_p (PATTERN (i2))))
      {
        last2 = i2;
+       /* Count everything except for unconditional jump as insn.  */
+       if (!simplejump_p (i2) && !returnjump_p (i2) && last1)
+ 	ninsns++;
        i2 = PREV_INSN (i2);
      }
  
*************** outgoing_edges_match (mode, bb1, bb2)
*** 958,968 ****
  
    /* If BB1 has only one successor, we may be looking at either an
       unconditional jump, or a fake edge to exit.  */
!   if (bb1->succ && !bb1->succ->succ_next)
      {
!       if (! bb2->succ || bb2->succ->succ_next)
  	return false;
!       return insns_match_p (mode, bb1->end, bb2->end);
      }
  
    /* Match conditional jumps - this may get tricky when fallthru and branch
--- 958,970 ----
  
    /* If BB1 has only one successor, we may be looking at either an
       unconditional jump, or a fake edge to exit.  */
!   if (bb1->succ && !bb1->succ->succ_next
!       && !(bb1->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)))
      {
!       if (! bb2->succ || bb2->succ->succ_next
! 	  || (bb2->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)))
  	return false;
!       return true;
      }
  
    /* Match conditional jumps - this may get tricky when fallthru and branch
*************** outgoing_edges_match (mode, bb1, bb2)
*** 970,976 ****
    if (bb1->succ
        && bb1->succ->succ_next
        && !bb1->succ->succ_next->succ_next
!       && any_condjump_p (bb1->end))
      {
        edge b1, f1, b2, f2;
        bool reverse, match;
--- 972,979 ----
    if (bb1->succ
        && bb1->succ->succ_next
        && !bb1->succ->succ_next->succ_next
!       && any_condjump_p (bb1->end)
!       && onlyjump_p (bb1->end))
      {
        edge b1, f1, b2, f2;
        bool reverse, match;
*************** outgoing_edges_match (mode, bb1, bb2)
*** 980,986 ****
        if (!bb2->succ
            || !bb2->succ->succ_next
  	  || bb1->succ->succ_next->succ_next
! 	  || !any_condjump_p (bb2->end))
  	return false;
  
        b1 = BRANCH_EDGE (bb1);
--- 983,990 ----
        if (!bb2->succ
            || !bb2->succ->succ_next
  	  || bb1->succ->succ_next->succ_next
! 	  || !any_condjump_p (bb2->end)
! 	  || !onlyjump_p (bb1->end))
  	return false;
  
        b1 = BRANCH_EDGE (bb1);
*************** outgoing_edges_match (mode, bb1, bb2)
*** 1087,1095 ****
    /* Search the outgoing edges, ensure that the counts do match, find possible
       fallthru and exception handling edges since these needs more
       validation.  */
!   for (e1 = bb1->succ, e2 = bb2->succ; e1 && e2;
         e1 = e1->succ_next, e2 = e2->succ_next)
      {
        if (e1->flags & EDGE_EH)
  	nehedges1++;
        if (e2->flags & EDGE_EH)
--- 1091,1106 ----
    /* Search the outgoing edges, ensure that the counts do match, find possible
       fallthru and exception handling edges since these needs more
       validation.  */
!   for (e1 = bb1->succ, e2 = bb2->succ; ;
         e1 = e1->succ_next, e2 = e2->succ_next)
      {
+       /* Ignore existence of fake edges.  They are not required to match.  */
+       if (e1 && (e1->flags & EDGE_FAKE))
+ 	e1 = e1->succ_next;
+       if (e2 && (e2->flags & EDGE_FAKE))
+ 	e2 = e2->succ_next;
+       if (!e2 || !e1)
+ 	break;
        if (e1->flags & EDGE_EH)
  	nehedges1++;
        if (e2->flags & EDGE_EH)



More information about the Gcc-patches mailing list