This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Overzealous cross-jump merging.
- To: gcc-patches at gcc dot gnu dot org
- Subject: Overzealous cross-jump merging.
- From: Richard Earnshaw <rearnsha at arm dot com>
- Date: Fri, 21 Sep 2001 15:35:26 +0100
- cc: Richard dot Earnshaw at arm dot com, Jan Hubicka <jh at suse dot cz>
- Organization: ARM Ltd.
- Reply-To: Richard dot Earnshaw at arm dot com
This is the first of two patches to cfgcleanup.c that is required to allow
ARM ports to bootstrap successfully.
If we have the following flow graph:
B1 B2 B3
| | |
Rn = Ry Rn = Ry Rn = 32
(note Ry == 32) (note Ry = 48) |
| | |
v | |
B4 <-------------+ |
<------------------------------+
Where all three branches have identical insns after the noted assignment,
then cross jumping will incorrectly merge all three as follows:
Step 1.
B1 and B2 are merged with new sub-block B5:
B1 B2 B3
| | |
v | |
B5<--------------+ |
Rn = Ry Rn = 32
(note Ry == 32) |
| |
v |
B4 <------------------------------+
Step 2.
The compiler then notes that B5 and B3 can be merged by substituting Rn =
32, giving:
B1 B2 B3
| | |
v | |
B5<--------------+ |
<-------------------------------+
Rn = 32
|
v
B4
However, this is now incorrect when running through B2, since for this
route Rn should have the value 48.
It isn't that the first merge was wrong, just that we have left inaccurate
notes around. The solution is just to remove the notes, since after the
first merge step the identity relationship no-longer holds (Ry can now be
either 32 or 48).
Bootstrapped on sparc-solaris2.5.1 and on arm-netbsd to the point where we
can compare generated object files (library building still broken).
* cfgcleanup.c (flow_find_cross_jump): Delete any REG_EQUAL notes
that would be invalid after a merge.
Index: cfgcleanup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgcleanup.c,v
retrieving revision 1.4
diff -p -r1.4 cfgcleanup.c
*** cfgcleanup.c 2001/09/16 20:21:23 1.4
--- cfgcleanup.c 2001/09/21 14:11:20
*************** flow_find_cross_jump (mode, bb1, bb2, f1
*** 583,588 ****
--- 589,610 ----
/* Don't begin a cross-jump with a USE or CLOBBER insn. */
if (GET_CODE (p1) != USE && GET_CODE (p1) != CLOBBER)
{
+ /* If the merged insns have different REG_EQUAL notes, then
+ remove them. */
+ rtx equiv1 = find_reg_equal_equiv_note (i1);
+ rtx equiv2 = find_reg_equal_equiv_note (i2);
+
+ if (equiv1 && !equiv2)
+ remove_note (i1, equiv1);
+ else if (!equiv1 && equiv2)
+ remove_note (i2, equiv2);
+ else if (equiv1 && equiv2
+ && !rtx_equal_p (XEXP (equiv1, 0), XEXP (equiv2, 0)))
+ {
+ remove_note (i1, equiv1);
+ remove_note (i2, equiv2);
+ }
+
afterlast1 = last1, afterlast2 = last2;
last1 = i1, last2 = i2;
ninsns++;