Global.c/multiple set insns tweak

Jan Hubicka hubicka@atrey.karlin.mff.cuni.cz
Mon Jan 10 04:31:00 GMT 2000


In multiple sets insns global makes the registers mentioned in outputs to
conflict with all registers used in inputs:

	      /* If INSN has multiple outputs, then any reg that dies here
		 and is used inside of an output
		 must conflict with the other outputs.

		 It is unsafe to use !single_set here since it will ignore an
		 unused output.  Just because an output is unused does not mean
		 the compiler can assume the side effect will not occur.
		 Consider if REG appears in the address of an output and we
		 reload the output.  If we allocate REG to the same hard
		 register as an unused output we could set the hard register
		 before the output reload insn.  */

I expect this is done because when reload attempts to output output reload,
it might end up in wrong move insn, because the register used in address was
clobbered by another set of the insn.

I am trying to model i386 movs? instructions correctly and they needs exactly
such insn (one set makes the string copy, while other set alters the ESI,
EDI and ECX registers).
The extra conflict results in very bad code even when it is completely
irrelevat, because the BLKmode address can not be reloaded.

So the patch makes global.c to extract insn and do the conflicts only for
real output operands...

This also helps to zero_extract and similar patterns.

Honza

San Jan  9 05:03:20 CET 2000  Jan Hubicka  <jh@suse.cz>

	* global.c (global_conflicts): Mark conflict only for real output
	operands in multiple set insns.

Index: egcs/gcc/global.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/global.c,v
retrieving revision 1.52
diff -c -3 -p -r1.52 global.c
*** global.c	1999/12/20 12:13:01	1.52
--- global.c	2000/01/10 12:27:44
*************** Boston, MA 02111-1307, USA.  */
*** 34,39 ****
--- 34,40 ----
  #include "reload.h"
  #include "output.h"
  #include "toplev.h"
+ #include "recog.h"
  
  /* This pass of the compiler performs global register allocation.
     It assigns hard register numbers to all the pseudo registers
*************** global_conflicts ()
*** 782,806 ****
  		 register as an unused output we could set the hard register
  		 before the output reload insn.  */
  	      if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn))
! 		for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
! 		  if (REG_NOTE_KIND (link) == REG_DEAD)
! 		    {
! 		      int used_in_output = 0;
! 		      int i;
! 		      rtx reg = XEXP (link, 0);
! 
! 		      for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
! 			{
! 			  rtx set = XVECEXP (PATTERN (insn), 0, i);
! 			  if (GET_CODE (set) == SET
! 			      && GET_CODE (SET_DEST (set)) != REG
! 			      && !rtx_equal_p (reg, SET_DEST (set))
! 			      && reg_overlap_mentioned_p (reg, SET_DEST (set)))
! 			    used_in_output = 1;
! 			}
! 		      if (used_in_output)
! 			mark_reg_conflicts (reg);
! 		    }
  
  	      /* Mark any registers set in INSN and then never used.  */
  
--- 783,812 ----
  		 register as an unused output we could set the hard register
  		 before the output reload insn.  */
  	      if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn))
! 		{
! 		  extract_insn (insn);
! 		  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
! 		    if (REG_NOTE_KIND (link) == REG_DEAD)
! 		      {
! 			int used_in_output = 0;
! 			int i;
! 			rtx reg = XEXP (link, 0);
! 
! 			for (i = recog_data.n_operands; i >= 0; i--)
! 			  {
! 			    rtx op = recog_data.operand[i];
! 			    if (recog_data.operand_type[i] != OP_IN
! 				&& GET_CODE (op) != REG
! 				&& (GET_CODE (op) != SUBREG
! 				    || GET_CODE (SUBREG_REG (op)) != REG)
! 				&& !rtx_equal_p (reg, op)
! 				&& reg_overlap_mentioned_p (reg, op))
! 			      used_in_output = 1;
! 			  }
! 			if (used_in_output)
! 			  mark_reg_conflicts (reg);
! 		      }
! 		}
  
  	      /* Mark any registers set in INSN and then never used.  */
  


More information about the Gcc-patches mailing list