re PR target/44707 (operand requires impossible reload)

PR target/44707
	* config/sparc/sparc-protos.h (sparc_legitimize_reload_address): New.
	* config/sparc/sparc.c: Include reload.h.
	(legitimize_tls_address): Rename into...
	(sparc_legitimize_tls_address): ...this.
	(legitimize_pic_address): Rename into...
	(sparc_legitimize_pic_address): ...this.
	(sparc_expand_move): Adjust to above renaming.
	(sparc_tls_referenced_p): Likewise.
	(sparc_legitimize_tls_address): Likewise.
	(sparc_legitimize_pic_address): Likewise.
	(sparc_legitimize_address): Likewise.
	(sparc_output_mi_thunk): Likewise.
	(sparc_legitimize_reload_address): New global function.  Recognize
	(lo_sum (high ...) ...) patterns generated by earlier passes.
	* config/sparc/sparc.h (LEGITIMIZE_RELOAD_ADDRESS): Use above function.

From-SVN: r162521
This commit is contained in:
Eric Botcazou 2010-07-25 21:46:32 +00:00 committed by Eric Botcazou
parent bfb7cccf06
commit 58e6223e92
4 changed files with 101 additions and 49 deletions

View File

@ -1,3 +1,22 @@
2010-07-25 Eric Botcazou <ebotcazou@adacore.com>
PR target/44707
* config/sparc/sparc-protos.h (sparc_legitimize_reload_address): New.
* config/sparc/sparc.c: Include reload.h.
(legitimize_tls_address): Rename into...
(sparc_legitimize_tls_address): ...this.
(legitimize_pic_address): Rename into...
(sparc_legitimize_pic_address): ...this.
(sparc_expand_move): Adjust to above renaming.
(sparc_tls_referenced_p): Likewise.
(sparc_legitimize_tls_address): Likewise.
(sparc_legitimize_pic_address): Likewise.
(sparc_legitimize_address): Likewise.
(sparc_output_mi_thunk): Likewise.
(sparc_legitimize_reload_address): New global function. Recognize
(lo_sum (high ...) ...) patterns generated by earlier passes.
* config/sparc/sparc.h (LEGITIMIZE_RELOAD_ADDRESS): Use above function.
2010-07-25 Eric Botcazou <ebotcazou@adacore.com>
PR target/44484

View File

@ -63,6 +63,8 @@ extern void emit_tfmode_cvt (enum rtx_code, rtx *);
extern bool legitimate_constant_p (rtx);
extern bool constant_address_p (rtx);
extern bool legitimate_pic_operand_p (rtx);
extern rtx sparc_legitimize_reload_address (rtx, enum machine_mode, int, int,
int, int *win);
extern void sparc_emit_call_insn (rtx, rtx);
extern void sparc_defer_case_vector (rtx, rtx, int);
extern bool sparc_expand_move (enum machine_mode, rtx *);

View File

@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfglayout.h"
#include "gimple.h"
#include "langhooks.h"
#include "reload.h"
#include "params.h"
#include "df.h"
#include "dwarf2out.h"
@ -416,8 +417,8 @@ static void sparc_va_start (tree, rtx);
static tree sparc_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
static bool sparc_vector_mode_supported_p (enum machine_mode);
static bool sparc_tls_referenced_p (rtx);
static rtx legitimize_tls_address (rtx);
static rtx legitimize_pic_address (rtx, rtx);
static rtx sparc_legitimize_tls_address (rtx);
static rtx sparc_legitimize_pic_address (rtx, rtx);
static rtx sparc_legitimize_address (rtx, rtx, enum machine_mode);
static bool sparc_mode_dependent_address_p (const_rtx);
static bool sparc_pass_by_reference (CUMULATIVE_ARGS *,
@ -1006,7 +1007,7 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
&& CONSTANT_P (operands[1])
&& sparc_tls_referenced_p (operands [1]))
{
operands[1] = legitimize_tls_address (operands[1]);
operands[1] = sparc_legitimize_tls_address (operands[1]);
return false;
}
@ -1014,7 +1015,7 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
if (flag_pic && CONSTANT_P (operands[1]))
{
if (pic_address_needs_scratch (operands[1]))
operands[1] = legitimize_pic_address (operands[1], NULL_RTX);
operands[1] = sparc_legitimize_pic_address (operands[1], NULL_RTX);
/* VxWorks does not impose a fixed gap between segments; the run-time
gap can be different from the object-file gap. We therefore can't
@ -1041,9 +1042,10 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
if (symbolic_operand (operands[1], mode))
{
operands[1] = legitimize_pic_address (operands[1],
reload_in_progress
? operands[0] : NULL_RTX);
operands[1]
= sparc_legitimize_pic_address (operands[1],
reload_in_progress
? operands[0] : NULL_RTX);
return false;
}
}
@ -3217,7 +3219,7 @@ sparc_tls_referenced_p (rtx x)
if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x))
return true;
/* That's all we handle in legitimize_tls_address for now. */
/* That's all we handle in sparc_legitimize_tls_address for now. */
return false;
}
@ -3225,7 +3227,7 @@ sparc_tls_referenced_p (rtx x)
this (thread-local) address. */
static rtx
legitimize_tls_address (rtx addr)
sparc_legitimize_tls_address (rtx addr)
{
rtx temp1, temp2, temp3, ret, o0, got, insn;
@ -3354,7 +3356,7 @@ legitimize_tls_address (rtx addr)
gcc_assert (GET_CODE (XEXP (addr, 0)) == PLUS);
base = legitimize_tls_address (XEXP (XEXP (addr, 0), 0));
base = sparc_legitimize_tls_address (XEXP (XEXP (addr, 0), 0));
offset = XEXP (XEXP (addr, 0), 1);
base = force_operand (base, NULL_RTX);
@ -3375,7 +3377,7 @@ legitimize_tls_address (rtx addr)
necessary. */
static rtx
legitimize_pic_address (rtx orig, rtx reg)
sparc_legitimize_pic_address (rtx orig, rtx reg)
{
bool gotdata_op = false;
@ -3424,10 +3426,12 @@ legitimize_pic_address (rtx orig, rtx reg)
if (gotdata_op)
{
if (TARGET_ARCH64)
insn = emit_insn (gen_movdi_pic_gotdata_op (reg, pic_offset_table_rtx,
insn = emit_insn (gen_movdi_pic_gotdata_op (reg,
pic_offset_table_rtx,
address, orig));
else
insn = emit_insn (gen_movsi_pic_gotdata_op (reg, pic_offset_table_rtx,
insn = emit_insn (gen_movsi_pic_gotdata_op (reg,
pic_offset_table_rtx,
address, orig));
}
else
@ -3457,9 +3461,9 @@ legitimize_pic_address (rtx orig, rtx reg)
}
gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), reg);
offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
base == reg ? NULL_RTX : reg);
base = sparc_legitimize_pic_address (XEXP (XEXP (orig, 0), 0), reg);
offset = sparc_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
base == reg ? NULL_RTX : reg);
if (GET_CODE (offset) == CONST_INT)
{
@ -3515,9 +3519,9 @@ sparc_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
return x;
if (sparc_tls_referenced_p (x))
x = legitimize_tls_address (x);
x = sparc_legitimize_tls_address (x);
else if (flag_pic)
x = legitimize_pic_address (x, NULL_RTX);
x = sparc_legitimize_pic_address (x, NULL_RTX);
else if (GET_CODE (x) == PLUS && CONSTANT_ADDRESS_P (XEXP (x, 1)))
x = gen_rtx_PLUS (Pmode, XEXP (x, 0),
copy_to_mode_reg (Pmode, XEXP (x, 1)));
@ -3532,6 +3536,55 @@ sparc_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
return x;
}
/* SPARC implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
replace the input X, or the original X if no replacement is called for.
The output parameter *WIN is 1 if the calling macro should goto WIN,
0 if it should not.
For SPARC, we wish to handle addresses by splitting them into
HIGH+LO_SUM pairs, retaining the LO_SUM in the memory reference.
This cuts the number of extra insns by one.
Do nothing when generating PIC code and the address is a symbolic
operand or requires a scratch register. */
rtx
sparc_legitimize_reload_address (rtx x, enum machine_mode mode,
int opnum, int type,
int ind_levels ATTRIBUTE_UNUSED, int *win)
{
/* Decompose SImode constants into HIGH+LO_SUM. */
if (CONSTANT_P (x)
&& (mode != TFmode || TARGET_ARCH64)
&& GET_MODE (x) == SImode
&& GET_CODE (x) != LO_SUM
&& GET_CODE (x) != HIGH
&& sparc_cmodel <= CM_MEDLOW
&& !(flag_pic
&& (symbolic_operand (x, Pmode) || pic_address_needs_scratch (x))))
{
x = gen_rtx_LO_SUM (GET_MODE (x), gen_rtx_HIGH (GET_MODE (x), x), x);
push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
opnum, (enum reload_type)type);
*win = 1;
return x;
}
/* We have to recognize what we have already generated above. */
if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == HIGH)
{
push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
opnum, (enum reload_type)type);
*win = 1;
return x;
}
*win = 0;
return x;
}
/* Return true if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for.
@ -9111,7 +9164,7 @@ sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
/* Delay emitting the PIC helper function because it needs to
change the section and we are emitting assembly code. */
load_pic_register (); /* clobbers %o7 */
scratch = legitimize_pic_address (funexp, scratch);
scratch = sparc_legitimize_pic_address (funexp, scratch);
seq = get_insns ();
end_sequence ();
emit_and_preserve (seq, spill_reg, spill_reg2);

View File

@ -1801,36 +1801,14 @@ do { \
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
macro is used in only one place: `find_reloads_address' in reload.c.
For SPARC 32, we wish to handle addresses by splitting them into
HIGH+LO_SUM pairs, retaining the LO_SUM in the memory reference.
This cuts the number of extra insns by one.
Do nothing when generating PIC code and the address is a
symbolic operand or requires a scratch register. */
#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
do { \
/* Decompose SImode constants into hi+lo_sum. We do have to \
rerecognize what we produce, so be careful. */ \
if (CONSTANT_P (X) \
&& (MODE != TFmode || TARGET_ARCH64) \
&& GET_MODE (X) == SImode \
&& GET_CODE (X) != LO_SUM && GET_CODE (X) != HIGH \
&& ! (flag_pic \
&& (symbolic_operand (X, Pmode) \
|| pic_address_needs_scratch (X))) \
&& sparc_cmodel <= CM_MEDLOW) \
{ \
X = gen_rtx_LO_SUM (GET_MODE (X), \
gen_rtx_HIGH (GET_MODE (X), X), X); \
push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL, \
BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \
OPNUM, TYPE); \
goto WIN; \
} \
/* ??? 64-bit reloads. */ \
macro is used in only one place: `find_reloads_address' in reload.c. */
#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
do { \
int win; \
(X) = sparc_legitimize_reload_address ((X), (MODE), (OPNUM), \
(int)(TYPE), (IND_LEVELS), &win); \
if (win) \
goto WIN; \
} while (0)
/* Specify the machine mode that this machine uses