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]

Re: bug fix for egcs/gcc/reload1.c


It turned out that it is crucial to clear after_call immediately when
the return register is copied in a single piece.  With the original
patch I got failures for SH -m1 -O0 when compiling execute/921029-1.c
and execute/conversion.c , respectively.

Here is a refined patch:

Fri Oct  2 16:54:08 1998  J"orn Rennecke <amylaar@cygnus.co.uk>

	* reload1.c (calculate_needs_all_insns, reload_as_needed):
	Don't clear after_call for a CLOBBER.
	Keep track of how many hard registers need to be copied from
	after_call, and don't clear after_call before we have seen
	that much copies, or we see a different instruction.

*** reload1.c-1998100116	Thu Oct  1 16:15:50 1998
--- reload1.c	Fri Oct  2 16:47:07 1998
*************** calculate_needs_all_insns (first, global
*** 1443,1448 ****
--- 1443,1449 ----
    rtx insn;
    int something_changed = 0;
    rtx after_call = 0;
+   int after_call_nregs;
    /* Keep track of which basic blocks are needing the reloads.  */
    int this_block = 0;
  
*************** calculate_needs_all_insns (first, global
*** 1481,1501 ****
  	  if (SMALL_REGISTER_CLASSES && GET_CODE (insn) == CALL_INSN)
  	    {
  	      if (GET_CODE (PATTERN (insn)) == SET)
! 		after_call = SET_DEST (PATTERN (insn));
  	      else if (GET_CODE (PATTERN (insn)) == PARALLEL
  		       && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
! 		after_call = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
  	      else
  		after_call = 0;
  	    }
  	  else if (SMALL_REGISTER_CLASSES && after_call != 0
  		   && !(GET_CODE (PATTERN (insn)) == SET
  			&& SET_DEST (PATTERN (insn)) == stack_pointer_rtx)
  		   && GET_CODE (PATTERN (insn)) != USE)
  	    {
  	      if (reg_referenced_p (after_call, PATTERN (insn)))
! 		avoid_return_reg = after_call;
! 	      after_call = 0;
  	    }
  
  	  /* If needed, eliminate any eliminable registers.  */
--- 1482,1525 ----
  	  if (SMALL_REGISTER_CLASSES && GET_CODE (insn) == CALL_INSN)
  	    {
  	      if (GET_CODE (PATTERN (insn)) == SET)
! 		{
! 		  after_call = SET_DEST (PATTERN (insn));
! 		  after_call_nregs = HARD_REGNO_NREGS (REGNO (after_call),
! 						       GET_MODE (after_call));
! 		}
  	      else if (GET_CODE (PATTERN (insn)) == PARALLEL
  		       && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
! 		{
! 		  after_call = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
! 		  after_call_nregs = HARD_REGNO_NREGS (REGNO (after_call),
! 						       GET_MODE (after_call));
! 		}
  	      else
  		after_call = 0;
  	    }
  	  else if (SMALL_REGISTER_CLASSES && after_call != 0
  		   && !(GET_CODE (PATTERN (insn)) == SET
  			&& SET_DEST (PATTERN (insn)) == stack_pointer_rtx)
+ 		   && GET_CODE (PATTERN (insn)) != CLOBBER
  		   && GET_CODE (PATTERN (insn)) != USE)
  	    {
  	      if (reg_referenced_p (after_call, PATTERN (insn)))
! 		{
! 		  avoid_return_reg = after_call;
! 		  if (! --after_call_nregs)
! 		    after_call = 0;
! 		  else
! 		    {
! 		      /* If INSN copies the return register in a single chunk,
! 			 clear after_call now.  */
! 		      rtx set = single_set (insn);
! 		      if (set && (GET_MODE_SIZE (GET_MODE (SET_DEST (set)))
! 				  == GET_MODE_SIZE (GET_MODE (after_call))))
! 			after_call = 0;
! 		    }
! 		}
! 	      else
! 		after_call = 0;
  	    }
  
  	  /* If needed, eliminate any eliminable registers.  */
*************** reload_as_needed (first, live_known)
*** 4111,4116 ****
--- 4135,4141 ----
    int this_block = 0;
    rtx x;
    rtx after_call = 0;
+   int after_call_nregs;
  
    bzero ((char *) spill_reg_rtx, sizeof spill_reg_rtx);
    bzero ((char *) spill_reg_store, sizeof spill_reg_store);
*************** reload_as_needed (first, live_known)
*** 4181,4201 ****
  	  if (SMALL_REGISTER_CLASSES && GET_CODE (insn) == CALL_INSN)
  	    {
  	      if (GET_CODE (PATTERN (insn)) == SET)
! 		after_call = SET_DEST (PATTERN (insn));
  	      else if (GET_CODE (PATTERN (insn)) == PARALLEL
  		       && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
! 		after_call = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
  	      else
  		after_call = 0;
  	    }
  	  else if (SMALL_REGISTER_CLASSES && after_call != 0
  		   && !(GET_CODE (PATTERN (insn)) == SET
  			&& SET_DEST (PATTERN (insn)) == stack_pointer_rtx)
  		   && GET_CODE (PATTERN (insn)) != USE)
  	    {
  	      if (reg_referenced_p (after_call, PATTERN (insn)))
! 		avoid_return_reg = after_call;
! 	      after_call = 0;
  	    }
  
  	  /* If this is a USE and CLOBBER of a MEM, ensure that any
--- 4206,4249 ----
  	  if (SMALL_REGISTER_CLASSES && GET_CODE (insn) == CALL_INSN)
  	    {
  	      if (GET_CODE (PATTERN (insn)) == SET)
! 		{
! 		  after_call = SET_DEST (PATTERN (insn));
! 		  after_call_nregs = HARD_REGNO_NREGS (REGNO (after_call),
! 						       GET_MODE (after_call));
! 		}
  	      else if (GET_CODE (PATTERN (insn)) == PARALLEL
  		       && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
! 		{
! 		  after_call = SET_DEST (XVECEXP (PATTERN (insn), 0, 0));
! 		  after_call_nregs = HARD_REGNO_NREGS (REGNO (after_call),
! 						       GET_MODE (after_call));
! 		}
  	      else
  		after_call = 0;
  	    }
  	  else if (SMALL_REGISTER_CLASSES && after_call != 0
  		   && !(GET_CODE (PATTERN (insn)) == SET
  			&& SET_DEST (PATTERN (insn)) == stack_pointer_rtx)
+ 		   && GET_CODE (PATTERN (insn)) != CLOBBER
  		   && GET_CODE (PATTERN (insn)) != USE)
  	    {
  	      if (reg_referenced_p (after_call, PATTERN (insn)))
! 		{
! 		  avoid_return_reg = after_call;
! 		  if (! --after_call_nregs)
! 		    after_call = 0;
! 		  else
! 		    {
! 		      /* If INSN copies the return register in a single chunk,
! 			 clear after_call now.  */
! 		      rtx set = single_set (insn);
! 		      if (set && (GET_MODE_SIZE (GET_MODE (SET_DEST (set)))
! 				  == GET_MODE_SIZE (GET_MODE (after_call))))
! 			after_call = 0;
! 		    }
! 		}
! 	      else
! 		after_call = 0;
  	    }
  
  	  /* If this is a USE and CLOBBER of a MEM, ensure that any


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