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]

bug fix for reload reg selection


For a multi-precision add, choose_reload_regs had allocated registers
0 and 1 for a RELOAD_FOR_INPUT reload - using inheritance - and asked
allocate_reload_regs to allocate another two registers for a RELOAD_OTHER
reload, using the same input, pseudo register 215.
alloacte_reload_reg checked register 1 and 2, and was told by
free_for_value_p that this group was OK - register 2 was genuinely free,
while register 1 already held the value that we wanted, pseudo 215.

Now, of course the different words of a multi-word pseudo are not
interchangable.  The appended patch makes reload_reg_free_for_value_p
honour this by considering a previously loaded value only as matching
if it was loaded into the very same register - not just into any
partially overlapping register.

Of course, the above described scenario begs the question why pseudo 215
was not inherited for both reloads in the first place.  But that is a
different story.

Wed Jan 24 13:55:59 2001  J"orn Rennecke <amylaar@redhat.com>

	* reload1.c (reload_reg_free_for_value_p): New parameter start_regno.
	Changed all callers.  Take it into account when deciding if a
	previously loaded value matches.

Index: reload1.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/reload1.c,v
diff -p -r1.287.2.3 -r1.287.2.4
*** reload1.c	2001/01/21 03:45:50
--- reload1.c	2001/01/24 14:10:42
*************** static void clear_reload_reg_in_use	PARA
*** 411,417 ****
  						 enum machine_mode));
  static int reload_reg_free_p		PARAMS ((unsigned int, int,
  						 enum reload_type));
! static int reload_reg_free_for_value_p	PARAMS ((int, int, enum reload_type,
  						 rtx, rtx, int, int));
  static int free_for_value_p		PARAMS ((int, enum machine_mode, int,
  						 enum reload_type, rtx, rtx,
--- 411,418 ----
  						 enum machine_mode));
  static int reload_reg_free_p		PARAMS ((unsigned int, int,
  						 enum reload_type));
! static int reload_reg_free_for_value_p	PARAMS ((int, int, int,
! 						 enum reload_type,
  						 rtx, rtx, int, int));
  static int free_for_value_p		PARAMS ((int, enum machine_mode, int,
  						 enum reload_type, rtx, rtx,
*************** int reload_spill_index[MAX_RELOADS];
*** 4725,4733 ****
  /* Subroutine of free_for_value_p, used to check a single register.  */
  
  static int
! reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
! 			     ignore_address_reloads)
!      int regno;
       int opnum;
       enum reload_type type;
       rtx value, out;
--- 4726,4734 ----
  /* Subroutine of free_for_value_p, used to check a single register.  */
  
  static int
! reload_reg_free_for_value_p (start_regno, regno, opnum, type, value, out,
! 			     reloadnum, ignore_address_reloads)
!      int start_regno, regno;
       int opnum;
       enum reload_type type;
       rtx value, out;
*************** reload_reg_free_for_value_p (regno, opnu
*** 4820,4826 ****
  	      <= HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)) - (unsigned)1)
  	  && i != reloadnum)
  	{
! 	  if (! rld[i].in || ! rtx_equal_p (rld[i].in, value)
  	      || rld[i].out || out)
  	    {
  	      int time2;
--- 4821,4832 ----
  	      <= HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)) - (unsigned)1)
  	  && i != reloadnum)
  	{
! 	  rtx value2 = rld[i].in;
! 
! 	  if (true_regnum (reg) != start_regno)
! 	    value2 = NULL_RTX;
! 	  if (! value2 || ! rtx_equal_p (value2, value)
! 	      || true_regnum (reg) != start_regno
  	      || rld[i].out || out)
  	    {
  	      int time2;
*************** reload_reg_free_for_value_p (regno, opnu
*** 4901,4907 ****
  		case RELOAD_OTHER:
  		  /* If there is no conflict in the input part, handle this
  		     like an output reload.  */
! 		  if (! rld[i].in || rtx_equal_p (rld[i].in, value))
  		    {
  		      time2 = MAX_RECOG_OPERANDS * 4 + 4;
  		      /* Earlyclobbered outputs must conflict with inputs.  */
--- 4907,4913 ----
  		case RELOAD_OTHER:
  		  /* If there is no conflict in the input part, handle this
  		     like an output reload.  */
! 		  if (! rld[i].in || rtx_equal_p (value2, value))
  		    {
  		      time2 = MAX_RECOG_OPERANDS * 4 + 4;
  		      /* Earlyclobbered outputs must conflict with inputs.  */
*************** reload_reg_free_for_value_p (regno, opnu
*** 4923,4929 ****
  		}
  	      if ((time1 >= time2
  		   && (! rld[i].in || rld[i].out
! 		       || ! rtx_equal_p (rld[i].in, value)))
  		  || (out && rld[reloadnum].out_reg
  		      && time2 >= MAX_RECOG_OPERANDS * 4 + 3))
  		return 0;
--- 4929,4935 ----
  		}
  	      if ((time1 >= time2
  		   && (! rld[i].in || rld[i].out
! 		       || ! rtx_equal_p (value2, value)))
  		  || (out && rld[reloadnum].out_reg
  		      && time2 >= MAX_RECOG_OPERANDS * 4 + 3))
  		return 0;
*************** free_for_value_p (regno, mode, opnum, ty
*** 4974,4981 ****
  {
    int nregs = HARD_REGNO_NREGS (regno, mode);
    while (nregs-- > 0)
!     if (! reload_reg_free_for_value_p (regno + nregs, opnum, type, value, out,
! 				       reloadnum, ignore_address_reloads))
        return 0;
    return 1;
  }
--- 4980,4988 ----
  {
    int nregs = HARD_REGNO_NREGS (regno, mode);
    while (nregs-- > 0)
!     if (! reload_reg_free_for_value_p (regno, regno + nregs, opnum, type,
! 				       value, out, reloadnum,
! 				       ignore_address_reloads))
        return 0;
    return 1;
  }

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