This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Crossjumping fix II
- From: Jan Hubicka <jh at suse dot cz>
- To: David Edelsohn <dje at watson dot ibm dot com>
- Cc: Jan Hubicka <jh at suse dot cz>, Zack Weinberg <zack at codesourcery dot com>, gcc-patches at gcc dot gnu dot org, rth at redhat dot com
- Date: Tue, 18 Dec 2001 15:46:00 +0100
- Subject: Crossjumping fix II
- References: <200112172003.PAA28958@makai.watson.ibm.com>
> 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)