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]
Other format: [Raw text]

[addrmodes] Tame LEGITIMIZE_ADDRESS


Following steps 1/2 in the message at http://gcc.gnu.org/ml/gcc-patches/2004-08/msg00511.html this patch simplifies the way LEGITIMIZE_ADDRESS works, and tames the control flow in memory_address to remove gotos.

We don't use the WIN label anymore and instead always check the returned address for legitimacy. Nine back-ends, including some of the most used ones (i386, ARM, SPARC), were doing so anyway. At the same time I'm removing the last occurrences of GO_IF_LEGITIMATE_ADDRESS in machine-dependent code.

In addition, defining LEGITIMIZE_ADDRESS is now optional.

Committed to branch. I'm not going to do any more goto-taming, and instead concentrate on the base/index and REG_OK_STRICT mess. I'm leaving on Saturday, and I'll start an assembly language comparison for the testsuite for all targets. For those that pass, I'll commit when I come back.

Then I'll tag the branch to merge it in 4.3, and start experimenting with automatically generating GO_IF_LEGITIMATE_ADDRESS and (maybe) other address-related target hooks.

Paolo
2006-08-24  Paolo Bonzini  <bonzini@gnu.org>

	* explow.c (memory_address_1): New.
	(memory_address): Use it.  Avoid gotos.  Test for the validity
	of the address returned by LEGITIMIZE_ADDRESS.

	* doc/tm.texi (LEGITIMIZE_ADDRESS): Discourage using
	GO_IF_LEGITIMATE_ADDRESS (and WIN) within the macro.

	* config/s390/s390.h (LEGITIMIZE_ADDRESS): Remove checks
	now performed by memory_address.
	* config/m32r/m32r.h (LEGITIMIZE_ADDRESS): Likewise.
	* config/i386/i386.h (LEGITIMIZE_ADDRESS): Likewise.
	* config/avr/avr.h (LEGITIMIZE_ADDRESS): Likewise.
	* config/m68hc11/m68hc11.h (LEGITIMIZE_ADDRESS): Likewise.
	* config/mn10300/mn10300.h (LEGITIMIZE_ADDRESS): Likewise.
	* config/arm/arm.h (LEGITIMIZE_ADDRESS): Likewise.
	* config/pa/pa.h (LEGITIMIZE_ADDRESS): Likewise.
	* config/sparc/sparc.h (LEGITIMIZE_ADDRESS): Likewise.

	* config/m68k/m68k.h (LEGITIMIZE_ADDRESS): Use memory_address_p.

	* config/cris/cris.h (LEGITIMIZE_ADDRESS): Undefine.
	* config/mt/mt.h (LEGITIMIZE_ADDRESS): Likewise.

Index: explow.c
===================================================================
*** explow.c	(revision 116179)
--- explow.c	(working copy)
***************
*** 395,400 ****
--- 395,421 ----
  #endif /* defined(POINTERS_EXTEND_UNSIGNED) */
  }
  
+ /* Try machine-dependent ways of modifying an illegitimate address
+    to be legitimate.  If we find one, return a new address (which
+    may still be invalid!).  Otherwise, return X.  */
+ 
+ static inline rtx
+ memory_address_1 (enum machine_mode mode ATTRIBUTE_UNUSED,
+ 		  rtx x, rtx oldx ATTRIBUTE_UNUSED)
+ {
+ #ifdef LEGITIMIZE_ADDRESS
+   /* Just in case this function is used somewhere else.  */
+   if (oldx == NULL_RTX)
+     oldx = x;
+ 
+   LEGITIMIZE_ADDRESS (x, oldx, mode, win);
+ 
+  win: ATTRIBUTE_UNUSED_LABEL
+ #endif
+   return x;
+ }
+ 
+ 
  /* Return something equivalent to X but valid as a memory address
     for something of mode MODE.  When X is not itself valid, this
     works by copying X or subexpressions of it into registers.  */
***************
*** 417,439 ****
       are visible.  But not if cse won't be done!  */
    else
      {
        if (! cse_not_expected && !REG_P (x))
  	x = break_out_memory_refs (x);
  
        /* At this point, any valid address is accepted.  */
        if (memory_address_p (mode, x))
! 	goto win;
  
        /* If it was valid before but breaking out memory refs invalidated it,
  	 use it the old way.  */
!       if (memory_address_p (mode, oldx))
! 	goto win2;
  
        /* Perform machine-dependent transformations on X
  	 in certain cases.  This is not necessary since the code
  	 below can handle all possible cases, but machine-dependent
  	 transformations can make better code.  */
!       LEGITIMIZE_ADDRESS (x, oldx, mode, win);
  
        /* PLUS and MULT can appear in special ways
  	 as the result of attempts to make an address usable for indexing.
--- 440,479 ----
       are visible.  But not if cse won't be done!  */
    else
      {
+       bool legitimate;
+ 
        if (! cse_not_expected && !REG_P (x))
  	x = break_out_memory_refs (x);
  
        /* At this point, any valid address is accepted.  */
        if (memory_address_p (mode, x))
! 	legitimate = true;
  
        /* If it was valid before but breaking out memory refs invalidated it,
  	 use it the old way.  */
!       else if (memory_address_p (mode, oldx))
! 	x = oldx, legitimate = true;
  
        /* Perform machine-dependent transformations on X
  	 in certain cases.  This is not necessary since the code
  	 below can handle all possible cases, but machine-dependent
  	 transformations can make better code.  */
!       else
! 	{
! 	  rtx newx = memory_address_1 (mode, x, oldx);
! 	  legitimate = newx != x && newx != oldx && memory_address_p (mode, newx);
! 	  x = newx;
! 	}
! 
!       if (legitimate)
! 	{
! 	  x = newx;
!           if (flag_force_addr && ! cse_not_expected && !REG_P (x))
! 	    {
! 	      x = force_operand (x, NULL_RTX);
! 	      x = force_reg (Pmode, x);
! 	    }
! 	}
  
        /* PLUS and MULT can appear in special ways
  	 as the result of attempts to make an address usable for indexing.
***************
*** 444,450 ****
  	 and index off of it.  We do this because it often makes
  	 shorter code, and because the addresses thus generated
  	 in registers often become common subexpressions.  */
!       if (GET_CODE (x) == PLUS)
  	{
  	  rtx constant_term = const0_rtx;
  	  rtx y = eliminate_constant_term (x, &constant_term);
--- 480,486 ----
  	 and index off of it.  We do this because it often makes
  	 shorter code, and because the addresses thus generated
  	 in registers often become common subexpressions.  */
!       else if (GET_CODE (x) == PLUS)
  	{
  	  rtx constant_term = const0_rtx;
  	  rtx y = eliminate_constant_term (x, &constant_term);
***************
*** 473,493 ****
  	 the register is a valid address.  */
        else
  	x = force_reg (Pmode, x);
- 
-       goto done;
- 
-     win2:
-       x = oldx;
-     win:
-       if (flag_force_addr && ! cse_not_expected && !REG_P (x))
- 	{
- 	  x = force_operand (x, NULL_RTX);
- 	  x = force_reg (Pmode, x);
- 	}
      }
  
-  done:
- 
    /* If we didn't change the address, we are done.  Otherwise, mark
       a reg as a pointer if we have REG or REG + CONST_INT.  */
    if (oldx == x)
--- 509,516 ----
Index: config/s390/s390.h
===================================================================
*** config/s390/s390.h	(revision 116179)
--- config/s390/s390.h	(working copy)
***************
*** 729,736 ****
  #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)                          \
  {                                                                       \
    (X) = legitimize_address (X, OLDX, MODE);                             \
-   if (memory_address_p (MODE, X))                                       \
-     goto WIN;                                                           \
  }
  
  /* Try a machine-dependent way of reloading an illegitimate address
--- 729,734 ----
Index: config/m32r/m32r.h
===================================================================
*** config/m32r/m32r.h	(revision 116179)
--- config/m32r/m32r.h	(working copy)
***************
*** 1257,1264 ****
      {								 \
        if (flag_pic)						 \
  	(X) = m32r_legitimize_pic_address (X, NULL_RTX);	 \
-       if (memory_address_p (MODE, X))				 \
- 	goto WIN;						 \
      }								 \
    while (0)
  
--- 1257,1262 ----
Index: config/i386/i386.h
===================================================================
*** config/i386/i386.h	(revision 116179)
--- config/i386/i386.h	(working copy)
***************
*** 1684,1691 ****
  #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)				\
  do {									\
    (X) = legitimize_address ((X), (OLDX), (MODE));			\
-   if (memory_address_p ((MODE), (X)))					\
-     goto WIN;								\
  } while (0)
  
  #define REWRITE_ADDRESS(X) rewrite_address (X)
--- 1684,1689 ----
Index: config/avr/avr.h
===================================================================
*** config/avr/avr.h	(revision 116179)
--- config/avr/avr.h	(working copy)
***************
*** 371,378 ****
  #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)				\
  {									\
    (X) = legitimize_address (X, OLDX, MODE);				\
-   if (memory_address_p (MODE, X))					\
-     goto WIN;								\
  }
  
  #define XEXP_(X,Y) (X)
--- 371,376 ----
Index: config/m68hc11/m68hc11.h
===================================================================
*** config/m68hc11/m68hc11.h	(revision 116179)
--- config/m68hc11/m68hc11.h	(working copy)
***************
*** 1231,1240 ****
  #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)                     \
  { rtx operand = (X);                                            \
    if (m68hc11_legitimize_address (&operand, (OLDX), (MODE)))	\
-     {                                                           \
        (X) = operand;                                            \
-       GO_IF_LEGITIMATE_ADDRESS (MODE,X,WIN);                    \
-     }                                                           \
  }
  
  /* Go to LABEL if ADDR (a legitimate address expression)
--- 1231,1237 ----
Index: config/cris/cris.h
===================================================================
*** config/cris/cris.h	(revision 116179)
--- config/cris/cris.h	(working copy)
***************
*** 1053,1059 ****
     sometimes, but I'm not sure that it may be fixed here, since it is
     already split up in several instructions (Is this still true?).
     FIXME: Check and adjust for gcc-2.9x.  */
! #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) {}
  
  /* Fix reloads known to cause suboptimal spilling.  */
  #define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, INDL, WIN)	\
--- 1053,1059 ----
     sometimes, but I'm not sure that it may be fixed here, since it is
     already split up in several instructions (Is this still true?).
     FIXME: Check and adjust for gcc-2.9x.  */
! /* #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) */
  
  /* Fix reloads known to cause suboptimal spilling.  */
  #define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, INDL, WIN)	\
Index: config/mt/mt.h
===================================================================
*** config/mt/mt.h	(revision 116179)
--- config/mt/mt.h	(working copy)
***************
*** 646,652 ****
  
  #define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X)
  
! #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) {}
  
  #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
  
--- 646,652 ----
  
  #define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X)
  
! /* #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) */
  
  #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
  
Index: config/mn10300/mn10300.h
===================================================================
*** config/mn10300/mn10300.h	(revision 116179)
--- config/mn10300/mn10300.h	(working copy)
***************
*** 769,778 ****
     opportunities to optimize the output.  */
  
  #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)  \
! { rtx orig_x = (X);				\
!   (X) = legitimize_address (X, OLDX, MODE);	\
!   if ((X) != orig_x && memory_address_p (MODE, X)) \
!     goto WIN; }
  
  /* Go to LABEL if ADDR (a legitimate address expression)
     has an effect that depends on the machine mode it is used for.  */
--- 769,776 ----
     opportunities to optimize the output.  */
  
  #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)  \
! { (X) = legitimize_address (X, OLDX, MODE);	\
! }
  
  /* Go to LABEL if ADDR (a legitimate address expression)
     has an effect that depends on the machine mode it is used for.  */
Index: config/m68k/m68k.h
===================================================================
*** config/m68k/m68k.h	(revision 116179)
--- config/m68k/m68k.h	(working copy)
***************
*** 816,822 ****
  	{ if (TARGET_CFV4E && GET_MODE_CLASS (MODE) == MODE_FLOAT)	\
  	    { COPY_ONCE (X); X = force_operand (X, 0);}			\
  	  goto WIN; }							\
!       if (ch) { GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN); }		\
        if (GET_CODE (XEXP (X, 0)) == REG					\
  	       || (GET_CODE (XEXP (X, 0)) == SIGN_EXTEND		\
  		   && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG		\
--- 816,822 ----
  	{ if (TARGET_CFV4E && GET_MODE_CLASS (MODE) == MODE_FLOAT)	\
  	    { COPY_ONCE (X); X = force_operand (X, 0);}			\
  	  goto WIN; }							\
!       if (ch && memory_address_p (MODE, X) goto WIN;			\
        if (GET_CODE (XEXP (X, 0)) == REG					\
  	       || (GET_CODE (XEXP (X, 0)) == SIGN_EXTEND		\
  		   && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG		\
Index: config/arm/arm.h
===================================================================
*** config/arm/arm.h	(revision 116179)
--- config/arm/arm.h	(working copy)
***************
*** 2001,2009 ****
      ARM_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN);	\
    else							\
      THUMB_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN);	\
- 							\
-   if (memory_address_p (MODE, X))			\
-     goto WIN;						\
  } while (0)
  
  /* Go to LABEL if ADDR (a legitimate address expression)
--- 2001,2006 ----
Index: config/pa/pa.h
===================================================================
*** config/pa/pa.h	(revision 116179)
--- config/pa/pa.h	(working copy)
***************
*** 1552,1561 ****
     opportunities to optimize the output.  */
  
  #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)	\
! { rtx orig_x = (X);				\
!   (X) = hppa_legitimize_address (X, OLDX, MODE);	\
!   if ((X) != orig_x && memory_address_p (MODE, X)) \
!     goto WIN; }
  
  /* Go to LABEL if ADDR (a legitimate address expression)
     has an effect that depends on the machine mode it is used for.  */
--- 1552,1558 ----
     opportunities to optimize the output.  */
  
  #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)	\
! { (X) = hppa_legitimize_address (X, OLDX, MODE);	}
  
  /* Go to LABEL if ADDR (a legitimate address expression)
     has an effect that depends on the machine mode it is used for.  */

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