Patch to improve jump.c delete_noop_moves

John Wehle john@feith.com
Sun Apr 8 08:49:00 GMT 2001


This change allows jump.c delete_noop_moves to handle cond_exec
and detect more no-op parallels.  The size of the patch is merely
due to changes to the indenting.  The patch passes make bootstrap
and check on i386-unknown-freebsd4.2.  It also passes make and check
on arm-elf and powerpc-eabisim.

Notes:

  1) This patch requires the single_set_2 simple set patch.

ChangeLog:

Sun Apr  8 02:03:59 EDT 2001  John Wehle  (john@feith.com)

	* jump.c (delete_noop_moves): Handle cond_exec.
	Use single_set_2 to find a single set.

Enjoy!

-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/jump.c.ORIGINAL	Sat Apr  7 00:37:24 2001
--- gcc/jump.c	Sun Apr  8 01:36:55 2001
*************** delete_noop_moves (f)
*** 952,1045 ****
        if (GET_CODE (insn) == INSN)
  	{
  	  register rtx body = PATTERN (insn);
  
! 	  /* Detect and delete no-op move instructions
! 	     resulting from not allocating a parameter in a register.  */
! 
! 	  if (GET_CODE (body) == SET && set_noop_p (body))
! 	    delete_computation (insn);
  
! 	  /* Detect and ignore no-op move instructions
! 	     resulting from smart or fortuitous register allocation.  */
  
! 	  else if (GET_CODE (body) == SET)
  	    {
- 	      int sreg = true_regnum (SET_SRC (body));
- 	      int dreg = true_regnum (SET_DEST (body));
  
! 	      if (sreg == dreg && sreg >= 0)
! 		delete_insn (insn);
! 	      else if (sreg >= 0 && dreg >= 0)
  		{
! 		  rtx trial;
! 		  rtx tem = find_equiv_reg (NULL_RTX, insn, 0,
! 					    sreg, NULL_PTR, dreg,
! 					    GET_MODE (SET_SRC (body)));
  
! 		  if (tem != 0
! 		      && GET_MODE (tem) == GET_MODE (SET_DEST (body)))
  		    {
! 		      /* DREG may have been the target of a REG_DEAD note in
! 			 the insn which makes INSN redundant.  If so, reorg
! 			 would still think it is dead.  So search for such a
! 			 note and delete it if we find it.  */
! 		      if (! find_regno_note (insn, REG_UNUSED, dreg))
! 			for (trial = prev_nonnote_insn (insn);
! 			     trial && GET_CODE (trial) != CODE_LABEL;
! 			     trial = prev_nonnote_insn (trial))
! 			  if (find_regno_note (trial, REG_DEAD, dreg))
! 			    {
! 			      remove_death (dreg, trial);
! 			      break;
! 			    }
  
! 		      /* Deleting insn could lose a death-note for SREG.  */
! 		      if ((trial = find_regno_note (insn, REG_DEAD, sreg)))
  			{
! 			  /* Change this into a USE so that we won't emit
! 			     code for it, but still can keep the note.  */
! 			  PATTERN (insn)
! 			    = gen_rtx_USE (VOIDmode, XEXP (trial, 0));
! 			  INSN_CODE (insn) = -1;
! 			  /* Remove all reg notes but the REG_DEAD one.  */
! 			  REG_NOTES (insn) = trial;
! 			  XEXP (trial, 1) = NULL_RTX;
  			}
! 		      else
! 			delete_insn (insn);
! 		    }
! 		}
! 	      else if (dreg >= 0 && CONSTANT_P (SET_SRC (body))
! 		       && find_equiv_reg (SET_SRC (body), insn, 0, dreg,
! 					  NULL_PTR, 0,
! 					  GET_MODE (SET_DEST (body))))
! 		{
! 		  /* This handles the case where we have two consecutive
! 		     assignments of the same constant to pseudos that didn't
! 		     get a hard reg.  Each SET from the constant will be
! 		     converted into a SET of the spill register and an
! 		     output reload will be made following it.  This produces
! 		     two loads of the same constant into the same spill
! 		     register.  */
! 
! 		  rtx in_insn = insn;
! 
! 		  /* Look back for a death note for the first reg.
! 		     If there is one, it is no longer accurate.  */
! 		  while (in_insn && GET_CODE (in_insn) != CODE_LABEL)
  		    {
! 		      if ((GET_CODE (in_insn) == INSN
! 			   || GET_CODE (in_insn) == JUMP_INSN)
! 			  && find_regno_note (in_insn, REG_DEAD, dreg))
  			{
! 			  remove_death (dreg, in_insn);
! 			  break;
  			}
- 		      in_insn = PREV_INSN (in_insn);
- 		    }
  
! 		  /* Delete the second load of the value.  */
! 		  delete_insn (insn);
  		}
  	    }
  	  else if (GET_CODE (body) == PARALLEL)
--- 964,1067 ----
        if (GET_CODE (insn) == INSN)
  	{
  	  register rtx body = PATTERN (insn);
+ 	  rtx set;
  
! 	  if (GET_CODE (body) == COND_EXEC)
! 	    body = COND_EXEC_CODE (body);
  
! 	  set = single_set_2 (insn, body);
  
! 	  if (set)
  	    {
  
! 	      /* Detect and delete no-op move instructions
! 		 resulting from not allocating a parameter in a register.  */
! 
! 	      if (set_noop_p (set))
! 		delete_computation (insn);
! 
! 	      /* Detect and ignore no-op move instructions
! 		 resulting from smart or fortuitous register allocation.  */
! 
! 	      else
  		{
! 		  int sreg = true_regnum (SET_SRC (set));
! 		  int dreg = true_regnum (SET_DEST (set));
  
! 		  if (sreg == dreg && sreg >= 0)
! 		    delete_insn (insn);
! 		  else if (sreg >= 0 && dreg >= 0)
  		    {
! 		      rtx trial;
! 		      rtx tem = find_equiv_reg (NULL_RTX, insn, 0,
! 						sreg, NULL_PTR, dreg,
! 						GET_MODE (SET_SRC (set)));
  
! 		      if (tem != 0
! 			  && GET_MODE (tem) == GET_MODE (SET_DEST (set)))
  			{
! 			  /* DREG may have been the target of a REG_DEAD note
! 			     in the insn which makes INSN redundant.  If so,
! 			     reorg would still think it is dead.  So search
! 			     for such a note and delete it if we find it.  */
! 			  if (! find_regno_note (insn, REG_UNUSED, dreg))
! 			    for (trial = prev_nonnote_insn (insn);
! 				 trial && GET_CODE (trial) != CODE_LABEL;
! 				 trial = prev_nonnote_insn (trial))
! 			      if (find_regno_note (trial, REG_DEAD, dreg))
! 				{
! 				  remove_death (dreg, trial);
! 				  break;
! 				}
! 
! 			  /* Deleting insn could lose a death-note for SREG.  */
! 			  if ((trial = find_regno_note (insn, REG_DEAD, sreg)))
! 			    {
! 			      /* Change this into a USE so that we won't emit
! 				 code for it, but still can keep the note.  */
! 			      PATTERN (insn)
! 				= gen_rtx_USE (VOIDmode, XEXP (trial, 0));
! 			      INSN_CODE (insn) = -1;
! 			      /* Remove all reg notes but the REG_DEAD one.  */
! 			      REG_NOTES (insn) = trial;
! 			      XEXP (trial, 1) = NULL_RTX;
! 			    }
! 			  else
! 			    delete_insn (insn);
  			}
! 		      }
! 		  else if (dreg >= 0 && CONSTANT_P (SET_SRC (set))
! 			   && find_equiv_reg (SET_SRC (set), insn, 0, dreg,
! 					      NULL_PTR, 0,
! 					      GET_MODE (SET_DEST (set))))
  		    {
! 		      /* This handles the case where we have two consecutive
! 			 assignments of the same constant to pseudos that didn't
! 			 get a hard reg.  Each SET from the constant will be
! 			 converted into a SET of the spill register and an
! 			 output reload will be made following it.  This produces
! 			 two loads of the same constant into the same spill
! 			 register.  */
! 
! 		      rtx in_insn = insn;
! 
! 		      /* Look back for a death note for the first reg.
! 			 If there is one, it is no longer accurate.  */
! 		      while (in_insn && GET_CODE (in_insn) != CODE_LABEL)
  			{
! 			  if ((GET_CODE (in_insn) == INSN
! 			       || GET_CODE (in_insn) == JUMP_INSN)
! 			      && find_regno_note (in_insn, REG_DEAD, dreg))
! 			    {
! 			      remove_death (dreg, in_insn);
! 			      break;
! 			    }
! 			  in_insn = PREV_INSN (in_insn);
  			}
  
! 		      /* Delete the second load of the value.  */
! 		      delete_insn (insn);
! 		    }
  		}
  	    }
  	  else if (GET_CODE (body) == PARALLEL)
-------------------------------------------------------------------------
|   Feith Systems  |   Voice: 1-215-646-8000  |  Email: john@feith.com  |
|    John Wehle    |     Fax: 1-215-540-5495  |                         |
-------------------------------------------------------------------------



More information about the Gcc-patches mailing list