This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[addrmodes] Tame LEGITIMIZE_ADDRESS
- From: Paolo Bonzini <paolo dot bonzini at lu dot unisi dot ch>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 24 Aug 2006 09:59:39 +0200
- Subject: [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. */