bug fix for reload reg selection

Joern Rennecke amylaar@cambridge.redhat.com
Wed Jan 24 08:40:00 GMT 2001


> 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.

Now, the reason was that the inheritance was done from an earlier non-reload
insn, by the find_equiv_reg route.  This code doesn't allow inheritance for
in-out reloads.  choose_reload_regs has two different mechanisms to do
inheritance, with baffling differences in the kind of inheritances they
accept.  I suppose they were both small and simple at the start and
gradually grow both bigger and more different.  At any rate, it seems time
to unify this code.  This makes reload1.c smaller and simpler as well as more
powerful.

This patch depends on the bugfix patches I sent earlier.

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

	* reload1.c (reload_reg_free_for_value_p): New parameter inheritance.
	Changed all callers.
	Ignore reload_reg_unavailable for read-only uses.
	(free_for_value_p): New parameters inheritance and insn.
	Changed all callers.  For read-only uses, check insn - if set - for
	clobbers of regno (using code broken out of choose_reload_regs).
	(reload_inheritance): New function, broken out of choose_reload_regs.
	(choose_reload_regs): Use it.  Allow rld[r].out != 0 for equivalences
	found with find_equiv_reg.

Index: reload1.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/reload1.c,v
retrieving revision 1.287.2.4
diff -p -r1.287.2.4 reload1.c
*** reload1.c	2001/01/24 14:10:42
--- reload1.c	2001/01/24 16:27:22
*************** static int reload_reg_free_p		PARAMS ((u
*** 413,422 ****
  						 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, int));
  static int reload_reg_reaches_end_p	PARAMS ((unsigned int, int,
  						 enum reload_type));
  static int allocate_reload_reg		PARAMS ((struct insn_chain *, int,
--- 413,422 ----
  						 enum reload_type));
  static int reload_reg_free_for_value_p	PARAMS ((int, int, int,
  						 enum reload_type,
! 						 rtx, rtx, int, int, int));
  static int free_for_value_p		PARAMS ((int, enum machine_mode, int,
  						 enum reload_type, rtx, rtx,
! 						 int, int, int, rtx));
  static int reload_reg_reaches_end_p	PARAMS ((unsigned int, int,
  						 enum reload_type));
  static int allocate_reload_reg		PARAMS ((struct insn_chain *, int,
*************** static int conflicts_with_override	PARAM
*** 425,430 ****
--- 425,432 ----
  static void failed_reload		PARAMS ((rtx, int));
  static int set_reload_reg		PARAMS ((int, int));
  static void choose_reload_regs_init	PARAMS ((struct insn_chain *, rtx *));
+ static void reload_inheritance PARAMS ((int, int, enum machine_mode mode, rtx,
+ 					rtx, unsigned int, enum reg_class));
  static void choose_reload_regs		PARAMS ((struct insn_chain *));
  static void merge_assigned_reloads	PARAMS ((rtx));
  static void emit_input_reload_insns	PARAMS ((struct insn_chain *,
*************** int reload_spill_index[MAX_RELOADS];
*** 4727,4739 ****
  
  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;
       int reloadnum;
!      int ignore_address_reloads;
  {
    int time1;
    /* Set if we see an input reload that must not share its reload register
--- 4729,4741 ----
  
  static int
  reload_reg_free_for_value_p (start_regno, regno, opnum, type, value, out,
! 			     reloadnum, ignore_address_reloads, inheritance)
       int start_regno, regno;
       int opnum;
       enum reload_type type;
       rtx value, out;
       int reloadnum;
!      int ignore_address_reloads, inheritance;
  {
    int time1;
    /* Set if we see an input reload that must not share its reload register
*************** reload_reg_free_for_value_p (start_regno
*** 4743,4757 ****
    int i;
    int copy = 0;
  
-   if (TEST_HARD_REG_BIT (reload_reg_unavailable, regno))
-     return 0;
- 
    if (out == const0_rtx)
      {
        copy = 1;
        out = NULL_RTX;
      }
  
    /* We use some pseudo 'time' value to check if the lifetimes of the
       new register use would overlap with the one of a previous reload
       that is not read-only or uses a different value.
--- 4745,4762 ----
    int i;
    int copy = 0;
  
    if (out == const0_rtx)
      {
        copy = 1;
        out = NULL_RTX;
      }
  
+   /* For read-only uses, the caller has already checked with
+      regno_clobbered_p if there is any problem with re-using this register.  */
+   if ((out || ! inheritance)
+       && TEST_HARD_REG_BIT (reload_reg_unavailable, regno))
+     return 0;
+ 
    /* We use some pseudo 'time' value to check if the lifetimes of the
       new register use would overlap with the one of a previous reload
       that is not read-only or uses a different value.
*************** reload_reg_free_for_value_p (start_regno
*** 4964,4988 ****
     When IGNORE_ADDRESS_RELOADS is set, we can not have conflicts with
     reloads that load an address for the very reload we are considering.
  
     The caller has to make sure that there is no conflict with the return
     register.  */
  
  static int
  free_for_value_p (regno, mode, opnum, type, value, out, reloadnum,
! 		  ignore_address_reloads)
       int regno;
       enum machine_mode mode;
       int opnum;
       enum reload_type type;
       rtx value, out;
       int reloadnum;
!      int ignore_address_reloads;
  {
!   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;
  }
--- 4969,5049 ----
     When IGNORE_ADDRESS_RELOADS is set, we can not have conflicts with
     reloads that load an address for the very reload we are considering.
  
+    If INHERITANCE is set, we won't set the reload register prior to use.
+ 
+    INSN is the insn that is being reloaded, provided here so that we can
+    check for conflicts with clobbers.  If it is set to NULL_RTX, that means
+    that this is a repeat call, where there is no need to check this again.
+ 
     The caller has to make sure that there is no conflict with the return
     register.  */
  
  static int
  free_for_value_p (regno, mode, opnum, type, value, out, reloadnum,
! 		  ignore_address_reloads, inheritance, insn)
       int regno;
       enum machine_mode mode;
       int opnum;
       enum reload_type type;
       rtx value, out;
       int reloadnum;
!      int ignore_address_reloads, inheritance;
!      rtx insn;
  {
!   int nregs;
! 
!   if (! insn)
!     /* Already checked before.  */
!     ;
!   else if ((out && out != const0_rtx)
! 	   || ! inheritance)
!     /* We will check later in reload_reg_free_for_value_p.  */
!     ;
!   else if (regno_clobbered_p (regno, insn, mode, 0))
!     switch (rld[reloadnum].when_needed)
!       {
!       case RELOAD_FOR_OTHER_ADDRESS:
!       case RELOAD_FOR_INPADDR_ADDRESS:
!       case RELOAD_FOR_INPUT_ADDRESS:
!       case RELOAD_FOR_OPADDR_ADDR:
! 	break;
!       case RELOAD_OTHER:
!       case RELOAD_FOR_INSN:
!       case RELOAD_FOR_INPUT:
!       case RELOAD_FOR_OPERAND_ADDRESS:
! 	/* If we are only copying, the value is no longer needed at the time
! 	   the clobber happens.  */
! 	if (out == const0_rtx)
! 	  break;
! 	/* Fall through.  */
!       default:
!       /* Note that this covers cases like RELOAD_FOR_OUTPUT_ADDRESS, where
! 	 even the copy would be too late to escape the clobber.  */
! 	return 0;
!       }
!   else if (regno_clobbered_p (regno, insn, mode, 1))
!     switch (rld[reloadnum].when_needed)
!       {
!       case RELOAD_FOR_OTHER_ADDRESS:
!       case RELOAD_FOR_INPADDR_ADDRESS:
!       case RELOAD_FOR_INPUT_ADDRESS:
!       case RELOAD_FOR_OPADDR_ADDR:
!       case RELOAD_FOR_OPERAND_ADDRESS:
!       case RELOAD_FOR_INPUT:
! 	break;
!       case RELOAD_OTHER:
!       case RELOAD_FOR_INSN:
! 	if (out == const0_rtx)
! 	  break;
! 	/* Fall through.  */
!       default:
! 	return 0;
!       }
!   for (nregs = HARD_REGNO_NREGS (regno, mode); nregs-- > 0; )
      if (! reload_reg_free_for_value_p (regno, regno + nregs, opnum, type,
  				       value, out, reloadnum,
! 				       ignore_address_reloads,
! 				       inheritance))
        return 0;
    return 1;
  }
*************** allocate_reload_reg (chain, r, last_relo
*** 5145,5151 ****
  		   && ! TEST_HARD_REG_BIT (reload_reg_used, regnum)
  		   && free_for_value_p (regnum, rld[r].mode, rld[r].opnum,
  					rld[r].when_needed, rld[r].in,
! 					rld[r].out, r, 1)))
  	      && TEST_HARD_REG_BIT (reg_class_contents[class], regnum)
  	      && HARD_REGNO_MODE_OK (regnum, rld[r].mode)
  	      /* Look first for regs to share, then for unshared.  But
--- 5206,5212 ----
  		   && ! TEST_HARD_REG_BIT (reload_reg_used, regnum)
  		   && free_for_value_p (regnum, rld[r].mode, rld[r].opnum,
  					rld[r].when_needed, rld[r].in,
! 					rld[r].out, r, 1, 0, chain->insn)))
  	      && TEST_HARD_REG_BIT (reg_class_contents[class], regnum)
  	      && HARD_REGNO_MODE_OK (regnum, rld[r].mode)
  	      /* Look first for regs to share, then for unshared.  But
*************** choose_reload_regs_init (chain, save_rel
*** 5261,5266 ****
--- 5322,5458 ----
  			      rld[i].when_needed, rld[i].mode);
  }
  
+ /* Subroutine of choose_reload_regs, try to do inheritance for a particular
+    choice of reload register.
+    R is the reload number.
+    I is the register number of the register we want to inherit.
+    MODE is the mode we inherit it in.
+    LAST_REG is the rtx showing how it was referred to before.
+    INSN is the insn being reloaded.
+    MAX_GROUP_SIZE and GROUP_CLASS are used to make sure we don't squander
+    any registers in the class we need for multi-register reloads on smaller
+    reloads.  */
+ static void
+ reload_inheritance (r, i, mode, last_reg, insn, max_group_size, group_class)
+      int r, i;
+      enum machine_mode mode;
+      rtx last_reg, insn;
+      unsigned int max_group_size;
+      enum reg_class group_class;
+ {
+   enum reg_class class = rld[r].class, last_class;
+   last_class = REGNO_REG_CLASS (i);
+ 
+   if (1
+       && HARD_REGNO_MODE_OK (i, rld[r].mode)
+       && (TEST_HARD_REG_BIT (reg_class_contents[(int) class], i)
+ 	  /* Even if we can't use this register as a reload
+ 	     register, we might use it for reload_override_in,
+ 	     if copying it to the desired class is cheap
+ 	     enough.  */
+ 	  || ((REGISTER_MOVE_COST (mode, last_class, class)
+ 	       < MEMORY_MOVE_COST (mode, class, 1))
+ #ifdef SECONDARY_INPUT_RELOAD_CLASS
+ 	      && (SECONDARY_INPUT_RELOAD_CLASS (class, mode,
+ 						last_reg)
+ 		  == NO_REGS)
+ #endif
+ #ifdef SECONDARY_MEMORY_NEEDED
+ 	      && ! SECONDARY_MEMORY_NEEDED (last_class, class,
+ 					    mode)
+ #endif
+ 	      ))
+ 
+       && (rld[r].nregs == max_group_size
+ 	  || ! TEST_HARD_REG_BIT (reg_class_contents[(int) group_class],
+ 				  i))
+       && free_for_value_p (i, rld[r].mode, rld[r].opnum,
+ 			   rld[r].when_needed, rld[r].in,
+ 			   const0_rtx, r, 1, 1, insn))
+     {
+       if (1)
+ 	{
+ 	  int i1;
+ 
+ 	  /* We found a register that contains the
+ 	     value we need.  If this register is the
+ 	     same as an `earlyclobber' operand of the
+ 	     current insn, just mark it as a place to
+ 	     reload from since we can't use it as the
+ 	     reload register itself.  */
+ 
+ 	  for (i1 = n_earlyclobbers - 1; i1 >= 0; i1--)
+ 	    if (reg_overlap_mentioned_for_reload_p (last_reg,
+ 						    reload_earlyclobbers[i1]))
+ 	      break;
+ 
+ 	  last_reg = (GET_MODE (last_reg) == mode
+ 		      ? last_reg : gen_rtx_REG (mode, i));
+ 
+ 	  /* Check that all hard registers are in the
+ 	     required class.  */
+ 	  if (i1 < 0)
+ 	    for (i1 = HARD_REGNO_NREGS (i, mode); i1 >= 0; i1--)
+ 	      if (! (TEST_HARD_REG_BIT
+ 		     (reg_class_contents[(int) rld[r].class],
+ 		      i + i1)))
+ 		break;
+ 
+ 	  if (i1 >= 0
+ 	      || ! (free_for_value_p (i, rld[r].mode,
+ 				      rld[r].opnum,
+ 				      rld[r].when_needed, rld[r].in,
+ 				      rld[r].out, r, 1, 1,
+ 				      NULL_RTX))
+ 	      /* Don't use it if we'd clobber a pseudo reg.  */
+ 	      || (TEST_HARD_REG_BIT (reg_used_in_insn, i)
+ 		  && rld[r].out
+ 		  && ! TEST_HARD_REG_BIT (reg_reloaded_dead, i))
+ 	      /* Don't clobber the frame pointer.  */
+ 	      || (i == HARD_FRAME_POINTER_REGNUM
+ 		  && rld[r].out)
+ 	      /* Don't really use the inherited spill reg
+ 		 if we need it wider than we've got it.  */
+ 	      || (GET_MODE_SIZE (rld[r].mode)
+ 		  > GET_MODE_SIZE (mode))
+ 
+ 	      /* If find_reloads chose reload_out as reload
+ 		 register, stay with it - that leaves the
+ 		 inherited register for subsequent reloads.  */
+ 	      || (rld[r].out && rld[r].reg_rtx
+ 		  && rtx_equal_p (rld[r].out, rld[r].reg_rtx)))
+ 	    {
+ 	      if (! rld[r].optional)
+ 		{
+ 		  reload_override_in[r] = last_reg;
+ 		  reload_inheritance_insn[r]
+ 		    = reg_reloaded_insn[i];
+ 		}
+ 	    }
+ 	  else
+ 	    {
+ 	      int k;
+ 	      int nr = HARD_REGNO_NREGS (i, rld[r].mode);
+ 	      /* We can use this as a reload reg.  */
+ 	      /* Mark the register as in use for this part of
+ 		 the insn.  */
+ 	      mark_reload_reg_in_use (i,
+ 				      rld[r].opnum,
+ 				      rld[r].when_needed,
+ 				      rld[r].mode);
+ 	      rld[r].reg_rtx = last_reg;
+ 	      reload_inherited[r] = 1;
+ 	      reload_inheritance_insn[r]
+ 		= reg_reloaded_insn[i];
+ 	      reload_spill_index[r] = i;
+ 	      for (k = 0; k < nr; k++)
+ 		SET_HARD_REG_BIT (reload_reg_used_for_inherit,
+ 				  i + k);
+ 	    }
+ 	}
+     }
+ }
+ 
  /* Assign hard reg targets for the pseudo-registers we must reload
     into hard regs for this insn.
     Also output the instructions to copy them in and out of the hard regs.
*************** choose_reload_regs (chain)
*** 5437,5448 ****
  
  	      if (regno >= 0 && reg_last_reload_reg[regno] != 0)
  		{
- 		  enum reg_class class = rld[r].class, last_class;
  		  rtx last_reg = reg_last_reload_reg[regno];
  		  enum machine_mode need_mode;
  
  		  i = REGNO (last_reg) + word;
- 		  last_class = REGNO_REG_CLASS (i);
  
  		  if (word == 0)
  		    need_mode = mode;
--- 5629,5638 ----
*************** choose_reload_regs (chain)
*** 5465,5496 ****
  		       >= GET_MODE_SIZE (need_mode))
  #endif
  		      && reg_reloaded_contents[i] == regno
! 		      && TEST_HARD_REG_BIT (reg_reloaded_valid, i)
! 		      && HARD_REGNO_MODE_OK (i, rld[r].mode)
! 		      && (TEST_HARD_REG_BIT (reg_class_contents[(int) class], i)
! 			  /* Even if we can't use this register as a reload
! 			     register, we might use it for reload_override_in,
! 			     if copying it to the desired class is cheap
! 			     enough.  */
! 			  || ((REGISTER_MOVE_COST (mode, last_class, class)
! 			       < MEMORY_MOVE_COST (mode, class, 1))
! #ifdef SECONDARY_INPUT_RELOAD_CLASS
! 			      && (SECONDARY_INPUT_RELOAD_CLASS (class, mode,
! 								last_reg)
! 				  == NO_REGS)
! #endif
! #ifdef SECONDARY_MEMORY_NEEDED
! 			      && ! SECONDARY_MEMORY_NEEDED (last_class, class,
! 							    mode)
! #endif
! 			      ))
! 
! 		      && (rld[r].nregs == max_group_size
! 			  || ! TEST_HARD_REG_BIT (reg_class_contents[(int) group_class],
! 						  i))
! 		      && free_for_value_p (i, rld[r].mode, rld[r].opnum,
! 					   rld[r].when_needed, rld[r].in,
! 					   const0_rtx, r, 1))
  		    {
  		      /* If a group is needed, verify that all the subsequent
  			 registers still have their values intact.  */
--- 5655,5661 ----
  		       >= GET_MODE_SIZE (need_mode))
  #endif
  		      && reg_reloaded_contents[i] == regno
! 		      && TEST_HARD_REG_BIT (reg_reloaded_valid, i))
  		    {
  		      /* If a group is needed, verify that all the subsequent
  			 registers still have their values intact.  */
*************** choose_reload_regs (chain)
*** 5503,5586 ****
  			  break;
  
  		      if (k == nr)
! 			{
! 			  int i1;
! 
! 			  last_reg = (GET_MODE (last_reg) == mode
! 				      ? last_reg : gen_rtx_REG (mode, i));
! 
! 			  /* We found a register that contains the
! 			     value we need.  If this register is the
! 			     same as an `earlyclobber' operand of the
! 			     current insn, just mark it as a place to
! 			     reload from since we can't use it as the
! 			     reload register itself.  */
! 
! 			  for (i1 = n_earlyclobbers - 1; i1 >= 0; i1--)
! 			    if (reg_overlap_mentioned_for_reload_p
! 				(reg_last_reload_reg[regno],
! 				 reload_earlyclobbers[i1]))
! 			      break;
! 
! 			  /* Check that all hard registers are in the
! 			     required class.  */
! 			  if (i1 < 0)
! 			    for (i1 = HARD_REGNO_NREGS (i, mode); i1 >= 0; i1--)
! 			      if (! (TEST_HARD_REG_BIT
! 				     (reg_class_contents[(int) rld[r].class],
! 				      i + i1)))
! 				break;
! 
! 			  if (i1 >= 0
! 			      || ! (free_for_value_p (i, rld[r].mode,
! 						      rld[r].opnum,
! 						      rld[r].when_needed, rld[r].in,
! 						      rld[r].out, r, 1))
! 			      /* Don't use it if we'd clobber a pseudo reg.  */
! 			      || (TEST_HARD_REG_BIT (reg_used_in_insn, i)
! 				  && rld[r].out
! 				  && ! TEST_HARD_REG_BIT (reg_reloaded_dead, i))
! 			      /* Don't clobber the frame pointer.  */
! 			      || (i == HARD_FRAME_POINTER_REGNUM
! 				  && rld[r].out)
! 			      /* Don't really use the inherited spill reg
! 				 if we need it wider than we've got it.  */
! 			      || (GET_MODE_SIZE (rld[r].mode)
! 				  > GET_MODE_SIZE (mode))
! 
! 			      /* If find_reloads chose reload_out as reload
! 				 register, stay with it - that leaves the
! 				 inherited register for subsequent reloads.  */
! 			      || (rld[r].out && rld[r].reg_rtx
! 				  && rtx_equal_p (rld[r].out, rld[r].reg_rtx)))
! 			    {
! 			      if (! rld[r].optional)
! 				{
! 				  reload_override_in[r] = last_reg;
! 				  reload_inheritance_insn[r]
! 				    = reg_reloaded_insn[i];
! 				}
! 			    }
! 			  else
! 			    {
! 			      int k;
! 			      /* We can use this as a reload reg.  */
! 			      /* Mark the register as in use for this part of
! 				 the insn.  */
! 			      mark_reload_reg_in_use (i,
! 						      rld[r].opnum,
! 						      rld[r].when_needed,
! 						      rld[r].mode);
! 			      rld[r].reg_rtx = last_reg;
! 			      reload_inherited[r] = 1;
! 			      reload_inheritance_insn[r]
! 				= reg_reloaded_insn[i];
! 			      reload_spill_index[r] = i;
! 			      for (k = 0; k < nr; k++)
! 				SET_HARD_REG_BIT (reload_reg_used_for_inherit,
! 						  i + k);
! 			    }
! 			}
  		    }
  		}
  	    }
--- 5668,5675 ----
  			  break;
  
  		      if (k == nr)
! 			reload_inheritance (r, i, mode, last_reg, insn,
! 					    max_group_size, group_class);
  		    }
  		}
  	    }
*************** choose_reload_regs (chain)
*** 5589,5595 ****
  	  if (inheritance
  	      && rld[r].in != 0
  	      && ! reload_inherited[r]
- 	      && rld[r].out == 0
  	      && (CONSTANT_P (rld[r].in)
  		  || GET_CODE (rld[r].in) == PLUS
  		  || GET_CODE (rld[r].in) == REG
--- 5678,5683 ----
*************** choose_reload_regs (chain)
*** 5633,5744 ****
  		    abort ();
  		}
  
- 	      /* If we found a spill reg, reject it unless it is free
- 		 and of the desired class.  */
- 	      if (equiv != 0
- 		  && ((TEST_HARD_REG_BIT (reload_reg_used_at_all, regno)
- 		       && ! free_for_value_p (regno, rld[r].mode,
- 					      rld[r].opnum, rld[r].when_needed,
- 					      rld[r].in, rld[r].out, r, 1))
- 		      || ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class],
- 					      regno)))
- 		equiv = 0;
- 
- 	      if (equiv != 0 && ! HARD_REGNO_MODE_OK (regno, rld[r].mode))
- 		equiv = 0;
- 
- 	      /* We found a register that contains the value we need.
- 		 If this register is the same as an `earlyclobber' operand
- 		 of the current insn, just mark it as a place to reload from
- 		 since we can't use it as the reload register itself.  */
- 
- 	      if (equiv != 0)
- 		for (i = 0; i < n_earlyclobbers; i++)
- 		  if (reg_overlap_mentioned_for_reload_p (equiv,
- 							  reload_earlyclobbers[i]))
- 		    {
- 		      if (! rld[r].optional)
- 			reload_override_in[r] = equiv;
- 		      equiv = 0;
- 		      break;
- 		    }
- 
- 	      /* If the equiv register we have found is explicitly clobbered
- 		 in the current insn, it depends on the reload type if we
- 		 can use it, use it for reload_override_in, or not at all.
- 		 In particular, we then can't use EQUIV for a
- 		 RELOAD_FOR_OUTPUT_ADDRESS reload.  */
- 
  	      if (equiv != 0)
!   		{
! 		  if (regno_clobbered_p (regno, insn, rld[r].mode, 0))
! 		    switch (rld[r].when_needed)
! 		      {
! 		      case RELOAD_FOR_OTHER_ADDRESS:
! 		      case RELOAD_FOR_INPADDR_ADDRESS:
! 		      case RELOAD_FOR_INPUT_ADDRESS:
! 		      case RELOAD_FOR_OPADDR_ADDR:
! 			break;
! 		      case RELOAD_OTHER:
! 		      case RELOAD_FOR_INPUT:
! 		      case RELOAD_FOR_OPERAND_ADDRESS:
! 			if (! rld[r].optional)
! 			  reload_override_in[r] = equiv;
! 			/* Fall through.  */
! 		      default:
! 			equiv = 0;
! 			break;
! 		      }
! 		  else if (regno_clobbered_p (regno, insn, rld[r].mode, 1))
! 		    switch (rld[r].when_needed)
! 		      {
! 		      case RELOAD_FOR_OTHER_ADDRESS:
! 		      case RELOAD_FOR_INPADDR_ADDRESS:
! 		      case RELOAD_FOR_INPUT_ADDRESS:
! 		      case RELOAD_FOR_OPADDR_ADDR:
! 		      case RELOAD_FOR_OPERAND_ADDRESS:
! 		      case RELOAD_FOR_INPUT:
! 			break;
! 		      case RELOAD_OTHER:
! 			if (! rld[r].optional)
! 			  reload_override_in[r] = equiv;
! 			/* Fall through.  */
! 		      default:
! 			equiv = 0;
! 			break;
! 		      }
! 		}
! 
! 	      /* If we found an equivalent reg, say no code need be generated
! 		 to load it, and use it as our reload reg.  */
! 	      if (equiv != 0 && regno != HARD_FRAME_POINTER_REGNUM)
! 		{
! 		  int nr = HARD_REGNO_NREGS (regno, rld[r].mode);
! 		  int k;
! 		  rld[r].reg_rtx = equiv;
! 		  reload_inherited[r] = 1;
! 
! 		  /* If reg_reloaded_valid is not set for this register,
! 		     there might be a stale spill_reg_store lying around.
! 		     We must clear it, since otherwise emit_reload_insns
! 		     might delete the store.  */
! 		  if (! TEST_HARD_REG_BIT (reg_reloaded_valid, regno))
! 		    spill_reg_store[regno] = NULL_RTX;
! 		  /* If any of the hard registers in EQUIV are spill
! 		     registers, mark them as in use for this insn.  */
! 		  for (k = 0; k < nr; k++)
! 		    {
! 		      i = spill_reg_order[regno + k];
! 		      if (i >= 0)
! 			{
! 			  mark_reload_reg_in_use (regno, rld[r].opnum,
! 						  rld[r].when_needed,
! 						  rld[r].mode);
! 			  SET_HARD_REG_BIT (reload_reg_used_for_inherit,
! 					    regno + k);
! 			}
! 		    }
! 		}
  	    }
  
  	  /* If we found a register to use already, or if this is an optional
--- 5721,5729 ----
  		    abort ();
  		}
  
  	      if (equiv != 0)
! 		reload_inheritance (r, regno, GET_MODE (equiv), equiv, insn,
! 				    max_group_size, group_class);
  	    }
  
  	  /* If we found a register to use already, or if this is an optional
*************** choose_reload_regs (chain)
*** 5886,5892 ****
  				  rld[r].opnum, rld[r].when_needed, rld[r].in,
  				  (reload_inherited[r]
  				   ? rld[r].out : const0_rtx),
! 				  r, 1))
  	    {
  	      if (pass)
  		continue;
--- 5871,5877 ----
  				  rld[r].opnum, rld[r].when_needed, rld[r].in,
  				  (reload_inherited[r]
  				   ? rld[r].out : const0_rtx),
! 				  r, 1, 1, NULL_RTX))
  	    {
  	      if (pass)
  		continue;
*************** emit_input_reload_insns (chain, rl, old,
*** 6211,6217 ****
        /* Don't use OLDEQUIV if any other reload changes it at an
  	 earlier stage of this insn or at this stage.  */
        if (! free_for_value_p (regno, rl->mode, rl->opnum, rl->when_needed,
! 			      rl->in, const0_rtx, j, 0))
  	oldequiv = 0;
  
        /* If it is no cheaper to copy from OLDEQUIV into the
--- 6196,6202 ----
        /* Don't use OLDEQUIV if any other reload changes it at an
  	 earlier stage of this insn or at this stage.  */
        if (! free_for_value_p (regno, rl->mode, rl->opnum, rl->when_needed,
! 			      rl->in, const0_rtx, j, 0, 1, insn))
  	oldequiv = 0;
  
        /* If it is no cheaper to copy from OLDEQUIV into the
*************** emit_input_reload_insns (chain, rl, old,
*** 6370,6376 ****
  	      uses the same reg first.  */
  	   && ! conflicts_with_override (reloadreg)
  	   && free_for_value_p (REGNO (reloadreg), rl->mode, rl->opnum,
! 				rl->when_needed, old, rl->out, j, 0))
      {
        rtx temp = PREV_INSN (insn);
        while (temp && GET_CODE (temp) == NOTE)
--- 6355,6362 ----
  	      uses the same reg first.  */
  	   && ! conflicts_with_override (reloadreg)
  	   && free_for_value_p (REGNO (reloadreg), rl->mode, rl->opnum,
! 				rl->when_needed, old, rl->out, j, 0, 0,
! 				NULL_RTX))
      {
        rtx temp = PREV_INSN (insn);
        while (temp && GET_CODE (temp) == NOTE)


More information about the Gcc-patches mailing list