Overzealous cross-jump merging.

Richard Earnshaw rearnsha@arm.com
Fri Sep 21 07:36:00 GMT 2001


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.




More information about the Gcc-patches mailing list