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]

make set_noop_p handle post-reload noops



Hi,
this patch moves the dirty hack to cleanup register allocation garbage to
set_noop_p.  The goal is to make flow.c's delete_noop_moves eliminate
the jump.c's one.

Hope that this will go later, but today is too busy.

Bootstrapped/regtested i686 togerhet with other today patches.

Honza
Ne čec 15 21:52:39 CEST 2001  Jan Hubicka  <jh@suse.cz>
	* cse.c (delete_trivially_dead_insns): Update call of set_noop_p;
	* flow.c (noop_move_p): Likewise.
	* gcse.c (hash_scan_set): Likewise.
	* jump.c (delete_noop_moves): Likewise.
	* reorg.c (split_insn): Likewise.
	* rtlanal.c (set_noop_p): Copy post-reload noop detection code from
	delete_noop_moves here.

*** /p1/jumpr2/jumpr/egcs/gcc/cse.c	Thu Jul 12 18:03:44 2001
--- cse.c	Sun Jul 15 20:20:23 2001
*************** delete_trivially_dead_insns (insns, nreg
*** 7598,7604 ****
  	live_insn = ! dead_libcall;
        else if (GET_CODE (PATTERN (insn)) == SET)
  	{
! 	  if (set_noop_p (PATTERN (insn)))
  	    ;
  
  #ifdef HAVE_cc0
--- 7598,7604 ----
  	live_insn = ! dead_libcall;
        else if (GET_CODE (PATTERN (insn)) == SET)
  	{
! 	  if (set_noop_p (PATTERN (insn), insn))
  	    ;
  
  #ifdef HAVE_cc0
*************** delete_trivially_dead_insns (insns, nreg
*** 7628,7634 ****
  
  	    if (GET_CODE (elt) == SET)
  	      {
! 		if (set_noop_p (elt))
  		  ;
  
  #ifdef HAVE_cc0
--- 7628,7634 ----
  
  	    if (GET_CODE (elt) == SET)
  	      {
! 		if (set_noop_p (elt, insn))
  		  ;
  
  #ifdef HAVE_cc0
*** /p1/jumpr2/jumpr/egcs/gcc/flow.c	Sat Jul 14 22:05:38 2001
--- flow.c	Sun Jul 15 21:05:09 2001
*************** noop_move_p (insn)
*** 4348,4354 ****
    if (find_reg_note (insn, REG_EQUAL, NULL_RTX))
      return 0;
  
!   if (GET_CODE (pat) == SET && set_noop_p (pat))
      return 1;
  
    if (GET_CODE (pat) == PARALLEL)
--- 4373,4379 ----
    if (find_reg_note (insn, REG_EQUAL, NULL_RTX))
      return 0;
  
!   if (GET_CODE (pat) == SET && set_noop_p (pat, insn))
      return 1;
  
    if (GET_CODE (pat) == PARALLEL)
*************** noop_move_p (insn)
*** 4364,4370 ****
  	      || GET_CODE (tem) == CLOBBER)
  	    continue;
  
! 	  if (GET_CODE (tem) != SET || ! set_noop_p (tem))
  	    return 0;
  	}
  
--- 4389,4395 ----
  	      || GET_CODE (tem) == CLOBBER)
  	    continue;
  
! 	  if (GET_CODE (tem) != SET || ! set_noop_p (tem, insn))
  	    return 0;
  	}
  
*** /p1/jumpr2/jumpr/egcs/gcc/gcse.c	Thu Jul 12 18:03:39 2001
--- gcse.c	Sun Jul 15 20:56:41 2001
*************** hash_scan_set (pat, insn, set_p)
*** 2205,2211 ****
  	  /* Is SET_SRC something we want to gcse?  */
  	  && want_to_gcse_p (src)
  	  /* Don't CSE a nop.  */
! 	  && ! set_noop_p (pat)
  	  /* Don't GCSE if it has attached REG_EQUIV note.
  	     At this point this only function parameters should have
  	     REG_EQUIV notes and if the argument slot is used somewhere
--- 2205,2211 ----
  	  /* Is SET_SRC something we want to gcse?  */
  	  && want_to_gcse_p (src)
  	  /* Don't CSE a nop.  */
! 	  && ! set_noop_p (pat, insn)
  	  /* Don't GCSE if it has attached REG_EQUIV note.
  	     At this point this only function parameters should have
  	     REG_EQUIV notes and if the argument slot is used somewhere
*** /p1/jumpr2/jumpr/egcs/gcc/jump.c	Sat Jul 14 20:59:50 2001
--- jump.c	Sun Jul 15 21:27:45 2001
*************** delete_noop_moves (f)
*** 807,813 ****
  	  /* 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
--- 346,352 ----
  	  /* 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, insn))
  	    delete_computation (insn);
  
  	  /* Detect and ignore no-op move instructions
*** /p1/jumpr2/jumpr/egcs/gcc/rtl.h	Sat Jul 14 21:00:04 2001
--- rtl.h	Sun Jul 15 21:30:08 2001
*************** extern int insn_dependent_p		PARAMS ((rt
*** 1385,1391 ****
  extern int reg_set_p			PARAMS ((rtx, rtx));
  extern rtx single_set_2			PARAMS ((rtx, rtx));
  extern int multiple_sets		PARAMS ((rtx));
! extern int set_noop_p			PARAMS ((rtx));
  extern rtx find_last_value		PARAMS ((rtx, rtx *, rtx, int));
  extern int refers_to_regno_p		PARAMS ((unsigned int, unsigned int,
  						 rtx, rtx *));
--- 1385,1391 ----
  extern int reg_set_p			PARAMS ((rtx, rtx));
  extern rtx single_set_2			PARAMS ((rtx, rtx));
  extern int multiple_sets		PARAMS ((rtx));
! extern int set_noop_p			PARAMS ((rtx, rtx));
  extern rtx find_last_value		PARAMS ((rtx, rtx *, rtx, int));
  extern int refers_to_regno_p		PARAMS ((unsigned int, unsigned int,
  						 rtx, rtx *));
*** /p1/jumpr2/jumpr/egcs/gcc/recog.c	Thu Jul 12 19:08:30 2001
--- recog.c	Sun Jul 15 22:14:01 2001
*************** split_insn (insn)
*** 2669,2682 ****
       disappear later in final.  Splitting such insns would
       break the code that handles REG_NO_CONFLICT blocks.  */
  
!   else if ((set = single_set (insn)) != NULL && set_noop_p (set))
      {
        /* Nops get in the way while scheduling, so delete them
           now if register allocation has already been done.  It
           is too risky to try to do this before register
           allocation, and there are unlikely to be very many
           nops then anyways.  */
!       if (reload_completed)
  	{
  	  PUT_CODE (insn, NOTE);
  	  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
--- 2669,2683 ----
       disappear later in final.  Splitting such insns would
       break the code that handles REG_NO_CONFLICT blocks.  */
  
!   else if ((set = single_set (insn)) != NULL && set_noop_p (set, 0))
      {
        /* Nops get in the way while scheduling, so delete them
           now if register allocation has already been done.  It
           is too risky to try to do this before register
           allocation, and there are unlikely to be very many
           nops then anyways.  */
!       if (reload_completed
! 	  && !find_reg_note (insn, REG_UNUSED, NULL_RTX))
  	{
  	  PUT_CODE (insn, NOTE);
  	  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
*** /p1/jumpr2/jumpr/egcs/gcc/rtlanal.c	Thu Jul 12 18:03:44 2001
--- rtlanal.c	Sun Jul 15 22:14:55 2001
*************** multiple_sets (insn)
*** 983,993 ****
  }
  
  /* Return nonzero if the destination of SET equals the source
!    and there are no side effects.  */
  
  int
! set_noop_p (set)
!      rtx set;
  {
    rtx src = SET_SRC (set);
    rtx dst = SET_DEST (set);
--- 983,996 ----
  }
  
  /* Return nonzero if the destination of SET equals the source
!    and there are no side effects.  
!  
!    Post reload, if INSN is present, function attempts to use information
!    provided by reload to kill even the non-obvious dead stores.  */
  
  int
! set_noop_p (set, insn)
!      rtx set, insn;
  {
    rtx src = SET_SRC (set);
    rtx dst = SET_DEST (set);
*************** set_noop_p (set)
*** 998,1012 ****
    if (GET_CODE (dst) == MEM && GET_CODE (src) == MEM)
      return rtx_equal_p (dst, src);
  
!   if (GET_CODE (dst) == SIGN_EXTRACT
!       || GET_CODE (dst) == ZERO_EXTRACT)
      return rtx_equal_p (XEXP (dst, 0), src)
! 	   && ! BYTES_BIG_ENDIAN && XEXP (dst, 2) == const0_rtx;
  
    if (GET_CODE (dst) == STRICT_LOW_PART)
      dst = XEXP (dst, 0);
  
!   if (GET_CODE (src) == SUBREG && GET_CODE (dst) == SUBREG)
      {
        if (SUBREG_BYTE (src) != SUBREG_BYTE (dst))
  	return 0;
--- 1001,1017 ----
    if (GET_CODE (dst) == MEM && GET_CODE (src) == MEM)
      return rtx_equal_p (dst, src);
  
!   if (GET_CODE (dst) == SIGN_EXTRACT || GET_CODE (dst) == ZERO_EXTRACT)
      return rtx_equal_p (XEXP (dst, 0), src)
!       && !BYTES_BIG_ENDIAN && XEXP (dst, 2) == const0_rtx;
  
    if (GET_CODE (dst) == STRICT_LOW_PART)
      dst = XEXP (dst, 0);
  
! 
!   /* Bypass subregs in case they do have equivalent SUBREG_BYTEs.  */
!   if (GET_CODE (src) == SUBREG && GET_CODE (dst) == SUBREG
!       && SUBREG_BYTE (src) == SUBREG_BYTE (dst))
      {
        if (SUBREG_BYTE (src) != SUBREG_BYTE (dst))
  	return 0;
*************** set_noop_p (set)
*** 1014,1021 ****
        dst = SUBREG_REG (dst);
      }
  
!   return (GET_CODE (src) == REG && GET_CODE (dst) == REG
! 	  && REGNO (src) == REGNO (dst));
  }
  
  /* Return the last thing that X was assigned from before *PINSN.  If VALID_TO
--- 1019,1104 ----
        dst = SUBREG_REG (dst);
      }
  
!   /* In case we still didn't eliminated the subregs, try to get around
!      the hard regs by simplify_subreg.  */
!   if (GET_CODE (src) == SUBREG)
!     {
!       rtx tem = simplify_subreg (GET_MODE (src), SUBREG_REG (src),
! 				 GET_MODE (SUBREG_REG (src)),
! 				 SUBREG_BYTE (src));
!       if (tem)
! 	src = tem;
!     }
!   if (GET_CODE (dst) == SUBREG)
!     {
!       rtx tem = simplify_subreg (GET_MODE (dst), SUBREG_REG (dst),
! 				 GET_MODE (SUBREG_REG (dst)),
! 				 SUBREG_BYTE (dst));
!       if (tem)
! 	dst = tem;
!     }
! 
!   if (GET_CODE (src) == REG && GET_CODE (dst) == REG
!       && REGNO (src) == REGNO (dst))
!     return 1;
! 
!   /* After reload try even harder to cleanup register allocation loossage. */
!   if (reload_completed && insn)
!     {
!       rtx trial;
!       int sreg = true_regnum (src);
!       int dreg = true_regnum (dst);
!       rtx tem = find_equiv_reg (NULL_RTX, insn, 0,
! 				sreg, NULL, dreg,
! 				GET_MODE (src));
!       if (tem != 0 && GET_MODE (tem) == GET_MODE (dst))
! 	{
! 	  /* 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;
! 		}
! 	  return 1;
! 	}
!       else if (dreg >= 0 && CONSTANT_P (src)
! 	       && find_equiv_reg (src, insn, 0, dreg,
! 				  NULL, 0, GET_MODE (dst)))
! 	{
! 	  /* 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);
! 	    }
! 	  return 1;
! 	}
!     }
!   return 0;
  }
  
  /* Return the last thing that X was assigned from before *PINSN.  If VALID_TO


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