REG_INC notes going AWOL during reload

Michael Hayes m.hayes@elec.canterbury.ac.nz
Sat Feb 20 15:41:00 GMT 1999


Jeffrey A Law writes:
 > More correctly, I think we need to move the REG_INC note to the insn which
 > has the address side effect.
 > 
 > Alternately we could strip away all the REG_INC notes and rebuild them.

The latter seems easier to implement.  Here's a patch to do that.

Could someone with access to a machine with autoincrement addressing
modes please perform a bootstrap test with this patch?

Michael.

Sun Feb 21 12:32:48 1999  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>

	* reload1.c (reload): Strip REG_INC notes.
	* flow.c (auto_inc_p): New function.
	(mark_set_1): Remove call to invalidate_mems_from_autoinc.
	(mark_used_regs): Restore REG_INC notes if reload_completed.
	Move calls to invalidate_mems_from_autoinc until after REG_INC
	notes restored.

Index: reload1.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/reload1.c,v
retrieving revision 1.129
diff -c -3 -p -r1.129 reload1.c
*** reload1.c	1999/02/10 09:13:41	1.129
--- reload1.c	1999/02/20 23:31:28
*************** reload (first, global, dumpfile)
*** 1124,1134 ****
       which are only valid during and after reload.  */
    reload_completed = 1;
  
!   /* Make a pass over all the insns and delete all USEs which we inserted
!      only to tag a REG_EQUAL note on them.  Remove all REG_DEAD and REG_UNUSED
!      notes.  Delete all CLOBBER insns and simplify (subreg (reg)) operands.
!      Also remove all REG_RETVAL and REG_LIBCALL notes since they are no longer
!      useful or accurate.  */
  
    for (insn = first; insn; insn = NEXT_INSN (insn))
      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
--- 1124,1135 ----
       which are only valid during and after reload.  */
    reload_completed = 1;
  
!   /* Make a pass over all the insns and delete all USEs which we
!      inserted only to tag a REG_EQUAL note on them.  Remove all
!      REG_INC, REG_DEAD, and REG_UNUSED notes.  Delete all CLOBBER
!      insns and simplify (subreg (reg)) operands.  Also remove all
!      REG_RETVAL and REG_LIBCALL notes since they are no longer useful
!      or accurate.  */
  
    for (insn = first; insn; insn = NEXT_INSN (insn))
      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
*************** reload (first, global, dumpfile)
*** 1150,1155 ****
--- 1151,1157 ----
  	  {
  	    if (REG_NOTE_KIND (*pnote) == REG_DEAD
  		|| REG_NOTE_KIND (*pnote) == REG_UNUSED
+ 		|| REG_NOTE_KIND (*pnote) == REG_INC
  		|| REG_NOTE_KIND (*pnote) == REG_RETVAL
  		|| REG_NOTE_KIND (*pnote) == REG_LIBCALL)
  	      *pnote = XEXP (*pnote, 1);
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/20 23:31:30
*************** 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));
*************** 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
--- 2363,2368 ----
*************** mark_set_1 (needed, dead, x, insn, signi
*** 2531,2536 ****
--- 2526,2556 ----
  
  #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
--- 2810,2830 ----
  	    }
  	}
  
  #ifdef AUTO_INC_DEC
+       if (auto_inc_p (x))
+ 	{
+ 	  /* Restore REG_INC notes stripped by reload.  */
+ 	  if (! final && reload_completed)
+ 	    REG_NOTES (insn)
+ 	      = gen_rtx (EXPR_LIST, REG_INC, XEXP (XEXP (x, 0), 0),
+ 			 REG_NOTES (insn));
+ 
+ 	  /* 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, x, insn);
  #endif
*************** mark_used_regs (needed, live, x, final, 
*** 2978,2983 ****
--- 3006,3025 ----
  	if (GET_CODE (testreg) == MEM)
  	  {
  #ifdef AUTO_INC_DEC
+ 	    if (auto_inc_p (testreg))
+ 	      {
+ 		/* Restore REG_INC notes stripped by reload.  */
+ 		if (! final && reload_completed)
+ 		  REG_NOTES (insn)
+ 		    = gen_rtx (EXPR_LIST, REG_INC, XEXP (XEXP (testreg, 0), 0),
+ 			       REG_NOTES (insn));
+ 
+ 		/* 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



More information about the Gcc-patches mailing list