Fix for deleted auto_inc instructions

Joern Rennecke amylaar@cygnus.co.uk
Sun Nov 15 23:13:00 GMT 1998


I have gotten some failures for the SH port as some sets were deleted where
the register being set was dead, but an address used POST_INC addressing.
The problem is that flow was written with the precondition in mind that
no auto_inc expressions exist before flow is finished.  Now that we
run flow another time after reload, this is no longer true.

I have appended a patch to fix this bug by making insn_dead_p return
zero if a REG_INC note is present.

If someone is more adventerous, (s)he can try to make flow replace insns
that are only needed for their addressing side effects with explicit adds.
However, I think in the short term we should first get the code working
again.

Mon Nov 16 07:04:50 1998  J"orn Rennecke <amylaar@cygnus.co.uk>

	* flow.c (insn_dead_p): New argument NOTES.  Changed all callers.

Index: flow.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/flow.c,v
retrieving revision 1.146
diff -p -r1.146 flow.c
*** flow.c	1998/10/28 07:17:12	1.146
--- flow.c	1998/11/16 07:03:28
*************** static int set_noop_p			PROTO((rtx));
*** 266,272 ****
  static int noop_move_p			PROTO((rtx));
  static void record_volatile_insns	PROTO((rtx));
  static void mark_regs_live_at_end	PROTO((regset));
! static int insn_dead_p			PROTO((rtx, regset, int));
  static int libcall_dead_p		PROTO((rtx, regset, rtx, rtx));
  static void mark_set_regs		PROTO((regset, regset, rtx,
  					       rtx, regset));
--- 266,272 ----
  static int noop_move_p			PROTO((rtx));
  static void record_volatile_insns	PROTO((rtx));
  static void mark_regs_live_at_end	PROTO((regset));
! static int insn_dead_p			PROTO((rtx, regset, int, rtx));
  static int libcall_dead_p		PROTO((rtx, regset, rtx, rtx));
  static void mark_set_regs		PROTO((regset, regset, rtx,
  					       rtx, regset));
*************** propagate_block (old, first, last, final
*** 1750,1756 ****
  	  register int i;
  	  rtx note = find_reg_note (insn, REG_RETVAL, NULL_RTX);
  	  int insn_is_dead
! 	    = (insn_dead_p (PATTERN (insn), old, 0)
  	       /* Don't delete something that refers to volatile storage!  */
  	       && ! INSN_VOLATILE (insn));
  	  int libcall_is_dead 
--- 1750,1756 ----
  	  register int i;
  	  rtx note = find_reg_note (insn, REG_RETVAL, NULL_RTX);
  	  int insn_is_dead
! 	    = (insn_dead_p (PATTERN (insn), old, 0, REG_NOTES (insn))
  	       /* Don't delete something that refers to volatile storage!  */
  	       && ! INSN_VOLATILE (insn));
  	  int libcall_is_dead 
*************** propagate_block (old, first, last, final
*** 1939,1954 ****
     (SET expressions whose destinations are registers dead after the insn).
     NEEDED is the regset that says which regs are alive after the insn.
  
!    Unless CALL_OK is non-zero, an insn is needed if it contains a CALL.  */
  
  static int
! insn_dead_p (x, needed, call_ok)
       rtx x;
       regset needed;
       int call_ok;
  {
    enum rtx_code code = GET_CODE (x);
  
    /* If setting something that's a reg or part of one,
       see if that register's altered value will be live.  */
  
--- 1939,1978 ----
     (SET expressions whose destinations are registers dead after the insn).
     NEEDED is the regset that says which regs are alive after the insn.
  
!    Unless CALL_OK is non-zero, an insn is needed if it contains a CALL.
  
+    If X is the entire body of an insn, NOTES contains the reg notes
+    pertaining to the insn.  */
+ 
  static int
! insn_dead_p (x, needed, call_ok, notes)
       rtx x;
       regset needed;
       int call_ok;
+      rtx notes ATTRIBUTE_UNUSED;
  {
    enum rtx_code code = GET_CODE (x);
  
+ #ifdef AUTO_INC_DEC
+   /* If flow is invoked after reload, we must take existing AUTO_INC
+      expresions into account.  */
+   if (reload_completed)
+     {
+       for ( ; notes; notes = XEXP (notes, 1))
+ 	{
+ 	  if (REG_NOTE_KIND (notes) == REG_INC)
+ 	    {
+ 	      int regno = REGNO (XEXP (notes, 0));
+ 
+ 	      /* Don't delete insns to set global regs.  */
+ 	      if ((regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
+ 		  || REGNO_REG_SET_P (needed, regno))
+ 		return 0;
+ 	    }
+ 	}
+     }
+ #endif
+ 
    /* If setting something that's a reg or part of one,
       see if that register's altered value will be live.  */
  
*************** insn_dead_p (x, needed, call_ok)
*** 2019,2025 ****
        for (i--; i >= 0; i--)
  	if (GET_CODE (XVECEXP (x, 0, i)) != CLOBBER
  	    && GET_CODE (XVECEXP (x, 0, i)) != USE
! 	    && ! insn_dead_p (XVECEXP (x, 0, i), needed, call_ok))
  	  return 0;
  
        return 1;
--- 2043,2049 ----
        for (i--; i >= 0; i--)
  	if (GET_CODE (XVECEXP (x, 0, i)) != CLOBBER
  	    && GET_CODE (XVECEXP (x, 0, i)) != USE
! 	    && ! insn_dead_p (XVECEXP (x, 0, i), needed, call_ok, NULL_RTX))
  	  return 0;
  
        return 1;
*************** libcall_dead_p (x, needed, note, insn)
*** 2066,2071 ****
--- 2090,2096 ----
        if (GET_CODE (r) == REG)
  	{
  	  rtx call = XEXP (note, 0);
+ 	  rtx call_pat;
  	  register int i;
  
  	  /* Find the call insn.  */
*************** libcall_dead_p (x, needed, note, insn)
*** 2079,2090 ****
  
  	  /* See if the hard reg holding the value is dead.
  	     If this is a PARALLEL, find the call within it.  */
! 	  call = PATTERN (call);
! 	  if (GET_CODE (call) == PARALLEL)
  	    {
! 	      for (i = XVECLEN (call, 0) - 1; i >= 0; i--)
! 		if (GET_CODE (XVECEXP (call, 0, i)) == SET
! 		    && GET_CODE (SET_SRC (XVECEXP (call, 0, i))) == CALL)
  		  break;
  
  	      /* This may be a library call that is returning a value
--- 2104,2115 ----
  
  	  /* See if the hard reg holding the value is dead.
  	     If this is a PARALLEL, find the call within it.  */
! 	  call_pat = PATTERN (call);
! 	  if (GET_CODE (call_pat) == PARALLEL)
  	    {
! 	      for (i = XVECLEN (call_pat, 0) - 1; i >= 0; i--)
! 		if (GET_CODE (XVECEXP (call_pat, 0, i)) == SET
! 		    && GET_CODE (SET_SRC (XVECEXP (call_pat, 0, i))) == CALL)
  		  break;
  
  	      /* This may be a library call that is returning a value
*************** libcall_dead_p (x, needed, note, insn)
*** 2093,2102 ****
  	      if (i < 0)
  		return 0;
  
! 	      call = XVECEXP (call, 0, i);
  	    }
  
! 	  return insn_dead_p (call, needed, 1);
  	}
      }
    return 1;
--- 2118,2127 ----
  	      if (i < 0)
  		return 0;
  
! 	      call_pat = XVECEXP (call_pat, 0, i);
  	    }
  
! 	  return insn_dead_p (call_pat, needed, 1, REG_NOTES (call));
  	}
      }
    return 1;



More information about the Gcc-patches mailing list