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]

removing combine_reloads


As discussed before, combining input and output reloads is unnecessary
since we can allocate the non-combined reloads to the same reload register,
and it leads to bugs with patterns live divmodsi4.
With the recent global.c:record_conflicts patch, the use of registers that
die has also become incorrect.

Fri Nov 12 20:32:19 1999  J"orn Rennecke <amylaar@cygnus.co.uk>

	* reload.c (combine_reloads): Deleted.
	(find_reloads): Don't call it.

Index: reload.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/reload.c,v
retrieving revision 1.90
diff -p -r1.90 reload.c
*** reload.c	1999/11/11 14:36:30	1.90
--- reload.c	1999/11/12 20:31:49
*************** static int push_reload		PROTO((rtx, rtx,
*** 246,252 ****
  				       enum machine_mode, enum machine_mode,
  				       int, int, int, enum reload_type));
  static void push_replacement	PROTO((rtx *, int, enum machine_mode));
- static void combine_reloads	PROTO((void));
  static int find_reusable_reload	PROTO((rtx *, rtx, enum reg_class,
  				       enum reload_type, int, int));
  static rtx find_dummy_reload	PROTO((rtx, rtx, rtx *, rtx *,
--- 246,251 ----
*************** loc_mentioned_in_p (loc, in)
*** 1576,1758 ****
    return 0;
  }
  
- /* If there is only one output reload, and it is not for an earlyclobber
-    operand, try to combine it with a (logically unrelated) input reload
-    to reduce the number of reload registers needed.
- 
-    This is safe if the input reload does not appear in
-    the value being output-reloaded, because this implies
-    it is not needed any more once the original insn completes.
- 
-    If that doesn't work, see we can use any of the registers that
-    die in this insn as a reload register.  We can if it is of the right
-    class and does not appear in the value being output-reloaded.  */
- 
- static void
- combine_reloads ()
- {
-   int i;
-   int output_reload = -1;
-   int secondary_out = -1;
-   rtx note;
- 
-   /* Find the output reload; return unless there is exactly one
-      and that one is mandatory.  */
- 
-   for (i = 0; i < n_reloads; i++)
-     if (rld[i].out != 0)
-       {
- 	if (output_reload >= 0)
- 	  return;
- 	output_reload = i;
-       }
- 
-   if (output_reload < 0 || rld[output_reload].optional)
-     return;
- 
-   /* An input-output reload isn't combinable.  */
- 
-   if (rld[output_reload].in != 0)
-     return;
- 
-   /* If this reload is for an earlyclobber operand, we can't do anything.  */
-   if (earlyclobber_operand_p (rld[output_reload].out))
-     return;
- 
-   /* Check each input reload; can we combine it?  */
- 
-   for (i = 0; i < n_reloads; i++)
-     if (rld[i].in && ! rld[i].optional && ! rld[i].nocombine
- 	/* Life span of this reload must not extend past main insn.  */
- 	&& rld[i].when_needed != RELOAD_FOR_OUTPUT_ADDRESS
- 	&& rld[i].when_needed != RELOAD_FOR_OUTADDR_ADDRESS
- 	&& rld[i].when_needed != RELOAD_OTHER
- 	&& (CLASS_MAX_NREGS (rld[i].class, rld[i].inmode)
- 	    == CLASS_MAX_NREGS (rld[output_reload].class,
- 				rld[output_reload].outmode))
- 	&& rld[i].inc == 0
- 	&& rld[i].reg_rtx == 0
- #ifdef SECONDARY_MEMORY_NEEDED
- 	/* Don't combine two reloads with different secondary
- 	   memory locations.  */
- 	&& (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum] == 0
- 	    || secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum] == 0
- 	    || rtx_equal_p (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum],
- 			    secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum]))
- #endif
- 	&& (SMALL_REGISTER_CLASSES
- 	    ? (rld[i].class == rld[output_reload].class)
- 	    : (reg_class_subset_p (rld[i].class,
- 				   rld[output_reload].class)
- 	       || reg_class_subset_p (rld[output_reload].class,
- 				      rld[i].class)))
- 	&& (MATCHES (rld[i].in, rld[output_reload].out)
- 	    /* Args reversed because the first arg seems to be
- 	       the one that we imagine being modified
- 	       while the second is the one that might be affected.  */
- 	    || (! reg_overlap_mentioned_for_reload_p (rld[output_reload].out,
- 						      rld[i].in)
- 		/* However, if the input is a register that appears inside
- 		   the output, then we also can't share.
- 		   Imagine (set (mem (reg 69)) (plus (reg 69) ...)).
- 		   If the same reload reg is used for both reg 69 and the
- 		   result to be stored in memory, then that result
- 		   will clobber the address of the memory ref.  */
- 		&& ! (GET_CODE (rld[i].in) == REG
- 		      && reg_overlap_mentioned_for_reload_p (rld[i].in,
- 							     rld[output_reload].out))))
- 	&& (reg_class_size[(int) rld[i].class]
- 	    || SMALL_REGISTER_CLASSES)
- 	/* We will allow making things slightly worse by combining an
- 	   input and an output, but no worse than that.  */
- 	&& (rld[i].when_needed == RELOAD_FOR_INPUT
- 	    || rld[i].when_needed == RELOAD_FOR_OUTPUT))
-       {
- 	int j;
- 
- 	/* We have found a reload to combine with!  */
- 	rld[i].out = rld[output_reload].out;
- 	rld[i].out_reg = rld[output_reload].out_reg;
- 	rld[i].outmode = rld[output_reload].outmode;
- 	/* Mark the old output reload as inoperative.  */
- 	rld[output_reload].out = 0;
- 	/* The combined reload is needed for the entire insn.  */
- 	rld[i].when_needed = RELOAD_OTHER;
- 	/* If the output reload had a secondary reload, copy it.  */
- 	if (rld[output_reload].secondary_out_reload != -1)
- 	  {
- 	    rld[i].secondary_out_reload
- 	      = rld[output_reload].secondary_out_reload;
- 	    rld[i].secondary_out_icode
- 	      = rld[output_reload].secondary_out_icode;
- 	  }
- 
- #ifdef SECONDARY_MEMORY_NEEDED
- 	/* Copy any secondary MEM.  */
- 	if (secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum] != 0)
- 	  secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[i].opnum]
- 	    = secondary_memlocs_elim[(int) rld[output_reload].outmode][rld[output_reload].opnum];
- #endif
- 	/* If required, minimize the register class.  */
- 	if (reg_class_subset_p (rld[output_reload].class,
- 				rld[i].class))
- 	  rld[i].class = rld[output_reload].class;
- 
- 	/* Transfer all replacements from the old reload to the combined.  */
- 	for (j = 0; j < n_replacements; j++)
- 	  if (replacements[j].what == output_reload)
- 	    replacements[j].what = i;
- 
- 	return;
-       }
- 
-   /* If this insn has only one operand that is modified or written (assumed
-      to be the first),  it must be the one corresponding to this reload.  It
-      is safe to use anything that dies in this insn for that output provided
-      that it does not occur in the output (we already know it isn't an
-      earlyclobber.  If this is an asm insn, give up.  */
- 
-   if (INSN_CODE (this_insn) == -1)
-     return;
- 
-   for (i = 1; i < insn_data[INSN_CODE (this_insn)].n_operands; i++)
-     if (insn_data[INSN_CODE (this_insn)].operand[i].constraint[0] == '='
- 	|| insn_data[INSN_CODE (this_insn)].operand[i].constraint[0] == '+')
-       return;
- 
-   /* See if some hard register that dies in this insn and is not used in
-      the output is the right class.  Only works if the register we pick
-      up can fully hold our output reload.  */
-   for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
-     if (REG_NOTE_KIND (note) == REG_DEAD
- 	&& GET_CODE (XEXP (note, 0)) == REG
- 	&& ! reg_overlap_mentioned_for_reload_p (XEXP (note, 0),
- 						 rld[output_reload].out)
- 	&& REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
- 	&& HARD_REGNO_MODE_OK (REGNO (XEXP (note, 0)), rld[output_reload].outmode)
- 	&& TEST_HARD_REG_BIT (reg_class_contents[(int) rld[output_reload].class],
- 			      REGNO (XEXP (note, 0)))
- 	&& (HARD_REGNO_NREGS (REGNO (XEXP (note, 0)), rld[output_reload].outmode)
- 	    <= HARD_REGNO_NREGS (REGNO (XEXP (note, 0)), GET_MODE (XEXP (note, 0))))
- 	/* Ensure that a secondary or tertiary reload for this output
- 	   won't want this register.  */
- 	&& ((secondary_out = rld[output_reload].secondary_out_reload) == -1
- 	    || (! (TEST_HARD_REG_BIT
- 		   (reg_class_contents[(int) rld[secondary_out].class],
- 		    REGNO (XEXP (note, 0))))
- 		&& ((secondary_out = rld[secondary_out].secondary_out_reload) == -1
- 		    ||  ! (TEST_HARD_REG_BIT
- 			   (reg_class_contents[(int) rld[secondary_out].class],
- 			    REGNO (XEXP (note, 0)))))))
- 	&& ! fixed_regs[REGNO (XEXP (note, 0))])
-       {
- 	rld[output_reload].reg_rtx
- 	  = gen_rtx_REG (rld[output_reload].outmode,
- 			 REGNO (XEXP (note, 0)));
- 	return;
-       }
- }
- 
  /* Try to find a reload register for an in-out reload (expressions IN and OUT).
     See if one of IN and OUT is a register that may be used;
     this is desirable since a spill-register won't be needed.
--- 1575,1580 ----
*************** find_reloads (insn, replace, ind_levels,
*** 3838,3848 ****
  	  rld[i].in = rld[i].reg_rtx;
        }
  #endif
- 
-   /* Perhaps an output reload can be combined with another
-      to reduce needs by one.  */
-   if (!goal_earlyclobber)
-     combine_reloads ();
  
    /* If we have a pair of reloads for parts of an address, they are reloading
       the same object, the operands themselves were not reloaded, and they
--- 3660,3665 ----


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