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]

fixes for m68k problems



This patch should fix the m68k bootstrapping problems.  It was actually a
latent bug.


        * rtlanal.c (multiple_sets): New function.
        * rtl.h (multiple_sets): Declare it.
        * local-alloc.c (wipe_dead_reg): Use it.
        * global.c (global_conflicts): Likewise.

Index: rtlanal.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/./gcc/rtlanal.c,v
retrieving revision 1.22
diff -c -3 -p -r1.22 rtlanal.c
*** rtlanal.c	1998/11/26 00:21:27	1.22
--- rtlanal.c	1998/12/13 07:02:17
*************** single_set (insn)
*** 690,695 ****
--- 690,727 ----
    
    return 0;
  }
+ 
+ /* Given an INSN, return nonzero if it has more than one SET, else return
+    zero.  */
+ 
+ rtx
+ multiple_sets (insn)
+      rtx insn;
+ {
+   rtx found;
+   int i;
+   
+   /* INSN must be an insn.  */
+   if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
+     return 0;
+ 
+   /* Only a PARALLEL can have multiple SETs.  */
+   if (GET_CODE (PATTERN (insn)) == PARALLEL)
+     {
+       for (i = 0, found = 0; i < XVECLEN (PATTERN (insn), 0); i++)
+ 	if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
+ 	  {
+ 	    /* If we have already found a SET, then return now.  */
+ 	    if (found)
+ 	      return 1;
+ 	    else
+ 	      found = 1;
+ 	  }
+     }
+   
+   /* Either zero or one SET.  */
+   return 0;
+ }
  
  /* Return the last thing that X was assigned from before *PINSN.  Verify that
     the object is not modified up to VALID_TO.  If it was, if we hit
Index: rtl.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/./gcc/rtl.h,v
retrieving revision 1.71
diff -c -3 -p -r1.71 rtl.h
*** rtl.h	1998/12/08 14:03:47	1.71
--- rtl.h	1998/12/13 07:02:19
*************** extern int no_labels_between_p		PROTO((r
*** 988,993 ****
--- 988,994 ----
  extern int modified_in_p		PROTO((rtx, rtx));
  extern int reg_set_p			PROTO((rtx, rtx));
  extern rtx single_set			PROTO((rtx));
+ extern rtx multiple_sets		PROTO((rtx));
  extern rtx find_last_value		PROTO((rtx, rtx *, rtx));
  extern int refers_to_regno_p		PROTO((int, int, rtx, rtx *));
  extern int reg_overlap_mentioned_p	PROTO((rtx, rtx));
Index: local-alloc.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/./gcc/local-alloc.c,v
retrieving revision 1.29
diff -c -3 -p -r1.29 local-alloc.c
*** local-alloc.c	1998/12/07 22:38:24	1.29
--- local-alloc.c	1998/12/13 07:02:22
*************** wipe_dead_reg (reg, output_p)
*** 1876,1884 ****
    /* If this insn has multiple results,
       and the dead reg is used in one of the results,
       extend its life to after this insn,
!      so it won't get allocated together with any other result of this insn.  */
    if (GET_CODE (PATTERN (this_insn)) == PARALLEL
!       && !single_set (this_insn))
      {
        int i;
        for (i = XVECLEN (PATTERN (this_insn), 0) - 1; i >= 0; i--)
--- 1876,1891 ----
    /* If this insn has multiple results,
       and the dead reg is used in one of the results,
       extend its life to after this insn,
!      so it won't get allocated together with any other result of this insn. 
! 
!      It is unsafe to use !single_set here since it will ignore an unused
!      output.  Just because an output is unused does not mean the compiler
!      can assume the side effect will not occur.   Consider if REG appears
!      in the address of an output and we reload the output.  If we allocate
!      REG to the same hard register as an unused output we could set the hard
!      register before the output reload insn.  */
    if (GET_CODE (PATTERN (this_insn)) == PARALLEL
!       && multiple_sets (this_insn))
      {
        int i;
        for (i = XVECLEN (PATTERN (this_insn), 0) - 1; i >= 0; i--)
Index: global.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/./gcc/global.c,v
retrieving revision 1.21
diff -c -3 -p -r1.21 global.c
*** global.c	1998/12/12 22:12:02	1.21
--- global.c	1998/12/13 07:02:28
*************** global_conflicts ()
*** 739,747 ****
  
  	      /* If INSN has multiple outputs, then any reg that dies here
  		 and is used inside of an output
! 		 must conflict with the other outputs.  */
  
! 	      if (GET_CODE (PATTERN (insn)) == PARALLEL && !single_set (insn))
  		for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
  		  if (REG_NOTE_KIND (link) == REG_DEAD)
  		    {
--- 739,754 ----
  
  	      /* If INSN has multiple outputs, then any reg that dies here
  		 and is used inside of an output
! 		 must conflict with the other outputs.
  
! 		 It is unsafe to use !single_set here since it will ignore an
! 		 unused output.  Just because an output is unused does not mean
! 		 the compiler can assume the side effect will not occur.
! 		 Consider if REG appears in the address of an output and we
! 		 reload the output.  If we allocate REG to the same hard
! 		 register as an unused output we could set the hard register
! 		 before the output reload insn.  */
! 	      if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn))
  		for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
  		  if (REG_NOTE_KIND (link) == REG_DEAD)
  		    {


Jeff Law (law@cygnus.com)
Cygnus Solutions		EGCS GNU Compiler System
http://www.cygnus.com		http://www.cygnus.com/egcs



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