bug fix for egcs/gcc/reload1.c

Joern Rennecke amylaar@cygnus.co.uk
Thu Oct 1 13:17:00 GMT 1998


In egcs, the sh3e port returns complex values in general registers.
That means we have to watch out for conflicts between the return register
and address reloads.  For execute/complex2.c -O0, in reload_as_needed, when
processing call_insn 74, after_call gets set to (reg:SC 0 r0)

The following instructions to copy the return value to a pseudo look like
this:

(insn 75 74 77 (clobber (concat:SC (reg:SF 72)
            (reg:SF 25 fr1))) -1 (nil)
    (nil))

(insn:HI 77 75 79 (parallel[ 
            (set (reg:SF 72)
                (reg:SF 0 r0))
            (clobber (scratch:SI))
        ] ) 129 {movsf_ie} (nil)
    (nil))

(insn:HI 79 77 80 (parallel[ 
            (set (reg:SF 25 fr1)
                (reg:SF 1 r1))
            (clobber (scratch:SI))
        ] ) 129 {movsf_ie} (nil)
    (nil))

When reload_as_needed processes the insn 75, it sees that it doesn't use
the return register, and clears after_call.  For insn 77, choose_reloads_reg
then happily allocates r0 as a spill register.

I have appended a patch.

Thu Oct  1 21:09:25 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	Thu Oct  1 20:58:02 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,1516 ----
  	  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
! 		after_call = 0;
  	    }
  
  	  /* If needed, eliminate any eliminable registers.  */
*************** reload_as_needed (first, live_known)
*** 4111,4116 ****
--- 4126,4132 ----
    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
--- 4197,4231 ----
  	  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
! 		after_call = 0;
  	    }
  
  	  /* If this is a USE and CLOBBER of a MEM, ensure that any



More information about the Gcc-patches mailing list