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]

Re: REG_INC notes going AWOL during reload


Jeffrey A Law writes:

 > mark_used_regs can be called multiple times for the same insn, which could
 > lead to multiple REG_INC notes added to the instruction.

 > Which can lead to multiple calls to propagate block for each block.  Then
 > propagate_block calls mark_used_regs, which causes us to add the REG_INC
 > note more than once to the same insn.

Yes, I forgot about this.  I think you meant multiple REG_INC notes
per register in the insn.

 > Seems to me we could deal handle adding the REG_INC notes in the same
 > loop that we remove them in reload.  ie, first we strip any REG_INC notes
 > off the insn.
 > 
 > Then we search the insn for any autoinc expressions and if we find one,
 > we add the appropriate notes.

Yes, this is probably a better approach although it is yet another pass.

 > Handling it in reload is also a little cleaner -- as far as the rest of
 > the compiler is concerned reload kept the REG_INC notes accurate.

In the interim, here's a patch to flow.c so that it is not dependent
upon the accuracy of the REG_INC notes.  This fixes the dead store bug.

Michael.

Tue Feb 23 11:07:27 1999  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>

	* flow.c (auto_inc_p): New function.
	(invalidate_mems_from_autoinc): Change argument from an insn
	to a mem rtx.  Use this instead of scanning insn notes for
	a REG_INC note.  All callers changed.
	(mark_set_1): Move call to invalidate_mems_from_autoinc into
	mark_used_regs.
	(mark_used_regs): Only call invalidate_mems_from_autoinc if
	auto_inc_p true.

Index: flow.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/flow.c,v
retrieving revision 1.99
diff -c -3 -p -r1.99 flow.c
*** flow.c	1999/01/27 01:42:19	1.99
--- flow.c	1999/02/22 22:05:33
*************** static void mark_set_regs		PROTO((regset
*** 278,283 ****
--- 278,284 ----
  static void mark_set_1			PROTO((regset, regset, rtx,
  					       rtx, regset));
  #ifdef AUTO_INC_DEC
+ static int auto_inc_p			PROTO((rtx));
  static void find_auto_inc		PROTO((regset, rtx, rtx));
  static int try_pre_increment_1		PROTO((rtx));
  static int try_pre_increment		PROTO((rtx, rtx, HOST_WIDE_INT));
*************** regno_clobbered_at_setjmp (regno)
*** 2226,2261 ****
  	  && REGNO_REG_SET_P (regs_live_at_setjmp, regno));
  }
  
! /* INSN references memory, possibly using autoincrement addressing modes.
     Find any entries on the mem_set_list that need to be invalidated due
     to an address change.  */
  static void
! invalidate_mems_from_autoinc (insn)
!      rtx insn;
  {
!   rtx note = REG_NOTES (insn);
!   for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
      {
!       if (REG_NOTE_KIND (note) == REG_INC)
!         {
!           rtx temp = mem_set_list;
!           rtx prev = NULL_RTX;
! 
!           while (temp)
! 	    {
! 	      if (reg_overlap_mentioned_p (XEXP (note, 0), XEXP (temp, 0)))
! 	        {
! 	          /* Splice temp out of list.  */
! 	          if (prev)
! 	            XEXP (prev, 1) = XEXP (temp, 1);
! 	          else
! 	            mem_set_list = XEXP (temp, 1);
! 	        }
! 	      else
! 	        prev = temp;
!               temp = XEXP (temp, 1);
! 	    }
  	}
      }
  }
  
--- 2227,2256 ----
  	  && REGNO_REG_SET_P (regs_live_at_setjmp, regno));
  }
  
! /* X references memory using autoincrement addressing modes.
     Find any entries on the mem_set_list that need to be invalidated due
     to an address change.  */
  static void
! invalidate_mems_from_autoinc (x)
!      rtx x;
  {
!   rtx temp = mem_set_list;
!   rtx prev = NULL_RTX;
!   rtx reg = XEXP (XEXP (x, 0), 0);
!   
!   while (temp)
      {
!       if (reg_overlap_mentioned_p (reg, XEXP (temp, 0)))
! 	{
! 	  /* Splice temp out of list.  */
! 	  if (prev)
! 	    XEXP (prev, 1) = XEXP (temp, 1);
! 	  else
! 	    mem_set_list = XEXP (temp, 1);
  	}
+       else
+ 	prev = temp;
+       temp = XEXP (temp, 1);
      }
  }
  
*************** mark_set_1 (needed, dead, x, insn, signi
*** 2362,2373 ****
  	}
      }
  
-   /* If the memory reference had embedded side effects (autoincrement
-      address modes.  Then we may need to kill some entries on the
-      memory set list.  */
-   if (insn && GET_CODE (reg) == MEM)
-     invalidate_mems_from_autoinc (insn);
- 
    if (GET_CODE (reg) == MEM && ! side_effects_p (reg)
        /* There are no REG_INC notes for SP, so we can't assume we'll see 
  	 everything that invalidates it.  To be safe, don't eliminate any
--- 2357,2362 ----
*************** mark_set_1 (needed, dead, x, insn, signi
*** 2531,2536 ****
--- 2520,2550 ----
  
  #ifdef AUTO_INC_DEC
  
+ /* Return 1 if X is a MEM with an autoincrement side effect
+    and the register is not the stack pointer.  */
+ static int
+ auto_inc_p (x)
+      rtx x;
+ {
+   if (GET_CODE (x) != MEM)
+     abort ();
+   x = XEXP (x, 0);
+   switch (GET_CODE (x))
+     {
+     case PRE_INC:
+     case POST_INC:
+     case PRE_DEC:
+     case POST_DEC:
+ 
+       /* There are no REG_INC notes for SP.  */
+       if (XEXP (x, 0) != stack_pointer_rtx)
+ 	return 1;
+     default:
+       break;
+     }
+   return 0;
+ }
+ 
  /* X is a MEM found in INSN.  See if we can convert it into an auto-increment
     reference.  */
  
*************** mark_used_regs (needed, live, x, final, 
*** 2790,2802 ****
  	    }
  	}
  
-       /* If the memory reference had embedded side effects (autoincrement
- 	 address modes.  Then we may need to kill some entries on the
- 	 memory set list.  */
-       if (insn)
- 	invalidate_mems_from_autoinc (insn);
- 
  #ifdef AUTO_INC_DEC
        if (final)
  	find_auto_inc (needed, x, insn);
  #endif
--- 2804,2818 ----
  	    }
  	}
  
  #ifdef AUTO_INC_DEC
+       if (auto_inc_p (x))
+ 	{
+ 	  /* If the memory reference had embedded side effects
+ 	     (autoincrement address modes.  Then we may need to kill
+ 	     some entries on the memory set list.  */
+ 	  invalidate_mems_from_autoinc (x);
+ 	}
+ 
        if (final)
  	find_auto_inc (needed, x, insn);
  #endif
*************** mark_used_regs (needed, live, x, final, 
*** 2978,2983 ****
--- 2994,3007 ----
  	if (GET_CODE (testreg) == MEM)
  	  {
  #ifdef AUTO_INC_DEC
+ 	    if (auto_inc_p (testreg))
+ 	      {
+ 		/* If the memory reference had embedded side effects
+ 		   (autoincrement address modes.  Then we may need to kill
+ 		   some entries on the memory set list.  */
+ 		invalidate_mems_from_autoinc (insn);
+ 	      }
+ 
  	    if (final)
  	      find_auto_inc (needed, testreg, insn);
  #endif







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