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]

Overzealous cross-jump merging.



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++;

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