REG_INC notes going AWOL during reload

Michael Hayes m.hayes@elec.canterbury.ac.nz
Sun Feb 28 18:15:00 GMT 1999


Michael Hayes writes:
 > Jeffrey A Law writes:
 >  > 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.

Please ignore this previous patch I sent for the meantime since I have
rewritten it to take advantage of the following patch which correctly
restores the REG_INC notes in reload.  Note, I don't have access to a
machine with autoincrement addressing modes that I can bootstrap with;
however, it appears to work correctly.

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

	* rtlanal.c (auto_inc_p): New function.
        * rtl.h (auto_inc_p): Prototype it.
	* reload1.c (add_auto_inc_notes): New function.
	(reload): Strip REG_INC notes and call add_auto_inc_notes
	for each insn to restore them correctly.

Index: rtlanal.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/rtlanal.c,v
retrieving revision 1.31
diff -c -3 -p -r1.31 rtlanal.c
*** rtlanal.c	1999/02/19 14:49:57	1.31
--- rtlanal.c	1999/02/23 22:23:45
*************** regno_use_in (regno, x)
*** 2253,2255 ****
--- 2253,2279 ----
  
    return NULL_RTX;
  }
+ 
+ 
+ /* Return 1 if X is an autoincrement side effect and the register is
+    not the stack pointer.  */
+ int
+ auto_inc_p (x)
+      rtx x;
+ {
+   switch (GET_CODE (x))
+     {
+     case PRE_INC:
+     case POST_INC:
+     case PRE_DEC:
+     case POST_DEC:
+     case PRE_MODIFY:
+     case POST_MODIFY:
+       /* There are no REG_INC notes for SP.  */
+       if (XEXP (x, 0) != stack_pointer_rtx)
+ 	return 1;
+     default:
+       break;
+     }
+   return 0;
+ }
Index: rtl.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/rtl.h,v
retrieving revision 1.86
diff -c -3 -p -r1.86 rtl.h
*** rtl.h	1999/02/08 21:39:31	1.86
--- rtl.h	1999/02/23 22:23:49
*************** typedef int (*rtx_function)             
*** 1038,1043 ****
--- 1038,1044 ----
  extern int for_each_rtx                 PROTO((rtx *, rtx_function, void *));
  extern int insn_first_p			PROTO((rtx, rtx));
  extern rtx regno_use_in			PROTO((int, rtx));
+ extern int auto_inc_p			PROTO((rtx));
  
  /* flow.c */
  
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/23 22:24:03
*************** static void reload_combine_note_use PROT
*** 443,448 ****
--- 443,451 ----
  static void reload_combine_note_store PROTO((rtx, rtx));
  static void reload_cse_move2add PROTO((rtx));
  static void move2add_note_store PROTO((rtx, rtx));
+ #ifdef AUTO_INC_DEC
+ static void add_auto_inc_notes PROTO((rtx, rtx));
+ #endif
  
  /* Initialize the reload pass once per compilation.  */
  
*************** 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')
--- 1127,1139 ----
       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.
!      Strip and regenerate REG_INC notes that may have been moved
!      around.  */
  
    for (insn = first; insn; insn = NEXT_INSN (insn))
      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
*************** reload (first, global, dumpfile)
*** 1150,1155 ****
--- 1155,1161 ----
  	  {
  	    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);
*************** reload (first, global, dumpfile)
*** 1157,1162 ****
--- 1163,1172 ----
  	      pnote = &XEXP (*pnote, 1);
  	  }
  
+ #ifdef AUTO_INC_DEC
+ 	add_auto_inc_notes (insn, PATTERN (insn));
+ #endif
+ 
  	/* And simplify (subreg (reg)) if it appears as an operand.  */
  	cleanup_subreg_operands (insn);
        }
*************** move2add_note_store (dst, set)
*** 10113,10115 ****
--- 10123,10155 ----
  	}
      }
  }
+ 
+ #ifdef AUTO_INC_DEC
+ static void
+ add_auto_inc_notes (insn, x)
+      rtx insn;
+      rtx x;
+ {
+   enum rtx_code code = GET_CODE (x);
+   char *fmt;
+   int i, j;
+ 
+   if (code == MEM && auto_inc_p (XEXP (x, 0)))
+     {
+       REG_NOTES (insn)
+ 	= gen_rtx_EXPR_LIST (REG_INC, XEXP (XEXP (x, 0), 0), REG_NOTES (insn));
+       return;
+     }
+ 
+   /* Scan all the operand sub-expressions.  */
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     {
+       if (fmt[i] == 'e')
+ 	add_auto_inc_notes (insn, XEXP (x, i));
+       else if (fmt[i] == 'E')
+ 	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ 	  add_auto_inc_notes (insn, XVECEXP (x, i, j));
+     }
+ }
+ #endif



More information about the Gcc-patches mailing list