reload.h, [...]: Revert March 15 change.

* reload.h, reload1.c (eliminate_regs), caller-save.c, dbxout.c,
	dwarfout.c, dwarf2out.c, reload.c, sdbout.c: Revert March 15 change.
	* reload.c (push_reload): If WORD_REGISTER_OPERATIONS, reload the
	SUBREG_REG if the word count is unchanged.
	* reload1.c (eliminate_regs) [case SET]: If W_R_O, preserve
	subregs of identical word size for push_reload.

From-SVN: r17105
This commit is contained in:
Richard Henderson 1997-12-15 09:55:58 -08:00 committed by Richard Henderson
parent a701efba7e
commit 1914f5da24
9 changed files with 84 additions and 80 deletions

View File

@ -1,3 +1,13 @@
Mon Dec 15 17:48:05 1997 Ricahrd Henderson <rth@cygnus.com>
* reload.h, reload1.c (eliminate_regs), caller-save.c, dbxout.c,
dwarfout.c, dwarf2out.c, reload.c, sdbout.c: Revert March 15 change.
* reload.c (push_reload): If WORD_REGISTER_OPERATIONS, reload the
SUBREG_REG if the word count is unchanged.
* reload1.c (eliminate_regs) [case SET]: If W_R_O, preserve
subregs of identical word size for push_reload.
Mon Dec 15 Mark Mitchell <mmitchell@usa.net> 11:41:32 1997
* toplev.c (rest_of_compilation): Don't call save_for_inline_copy

View File

@ -19,6 +19,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include <stdio.h>
#include "rtl.h"
#include "insn-config.h"
#include "flags.h"
@ -335,7 +336,7 @@ setup_save_areas (pchanged)
for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++)
if (regno_save_mem[i][j] != 0)
ok &= strict_memory_address_p (GET_MODE (regno_save_mem[i][j]),
XEXP (eliminate_regs (regno_save_mem[i][j], 0, NULL_RTX, 1), 0));
XEXP (eliminate_regs (regno_save_mem[i][j], 0, NULL_RTX), 0));
return ok;
}

View File

@ -1863,7 +1863,7 @@ dbxout_symbol (decl, local)
/* else it is something we handle like a normal variable. */
}
DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX, 0);
DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX);
#ifdef LEAF_REG_REMAP
if (leaf_function)
leaf_renumber_regs_insn (DECL_RTL (decl));
@ -2184,8 +2184,8 @@ dbxout_parms (parms)
/* Perform any necessary register eliminations on the parameter's rtl,
so that the debugging output will be accurate. */
DECL_INCOMING_RTL (parms)
= eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX, 0);
DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX, 0);
= eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX);
DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX);
#ifdef LEAF_REG_REMAP
if (leaf_function)
{

View File

@ -6968,7 +6968,7 @@ add_location_or_const_value_attribute (die, decl)
if (rtl == NULL_RTX)
return;
rtl = eliminate_regs (rtl, 0, NULL_RTX, 0);
rtl = eliminate_regs (rtl, 0, NULL_RTX);
#ifdef LEAF_REG_REMAP
if (leaf_function)
leaf_renumber_regs_insn (rtl);

View File

@ -1866,7 +1866,7 @@ output_bound_representation (bound, dim_num, u_or_l)
if (TREE_CODE (bound) == SAVE_EXPR)
output_loc_descriptor
(eliminate_regs (SAVE_EXPR_RTL (bound), 0, NULL_RTX, 0));
(eliminate_regs (SAVE_EXPR_RTL (bound), 0, NULL_RTX));
}
ASM_OUTPUT_LABEL (asm_out_file, end_label);
@ -2409,7 +2409,7 @@ location_or_const_value_attribute (decl)
if (rtl == NULL_RTX)
return;
rtl = eliminate_regs (rtl, 0, NULL_RTX, 0);
rtl = eliminate_regs (rtl, 0, NULL_RTX);
#ifdef LEAF_REG_REMAP
if (leaf_function)
leaf_renumber_regs_insn (rtl);

View File

@ -670,7 +670,7 @@ get_secondary_mem (x, mode, opnum, type)
/* Get a version of the address doing any eliminations needed. If that
didn't give us a new MEM, make a new one if it isn't valid. */
loc = eliminate_regs (secondary_memlocs[(int) mode], VOIDmode, NULL_RTX, 0);
loc = eliminate_regs (secondary_memlocs[(int) mode], VOIDmode, NULL_RTX);
mem_valid = strict_memory_address_p (mode, XEXP (loc, 0));
if (! mem_valid && loc == secondary_memlocs[(int) mode])
@ -985,7 +985,13 @@ push_reload (in, out, inloc, outloc, class,
&& REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
|| GET_CODE (SUBREG_REG (out)) == MEM)
&& ((GET_MODE_SIZE (outmode)
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))))
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
#ifdef WORD_REGISTER_OPERATIONS
|| ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD ==
((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1)
/ UNITS_PER_WORD))
#endif
))
|| (GET_CODE (SUBREG_REG (out)) == REG
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
&& ((GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
@ -2599,7 +2605,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
/* We must rerun eliminate_regs, in case the elimination
offsets have changed. */
rtx address = XEXP (eliminate_regs (reg_equiv_memory_loc[regno],
0, NULL_RTX, 0),
0, NULL_RTX),
0);
if (rtx_varies_p (address))
@ -4097,7 +4103,7 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest)
/* We must rerun eliminate_regs, in case the elimination
offsets have changed. */
rtx addr = XEXP (eliminate_regs (reg_equiv_memory_loc[regno], 0,
NULL_RTX, 0),
NULL_RTX),
0);
if (rtx_varies_p (addr))
@ -4181,7 +4187,7 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest)
/* We must rerun eliminate_regs, in case the elimination
offsets have changed. */
rtx addr = XEXP (eliminate_regs (reg_equiv_memory_loc[regno], 0,
NULL_RTX, 0),
NULL_RTX),
0);
if (BYTES_BIG_ENDIAN)
{
@ -4221,8 +4227,7 @@ make_memloc (ad, regno)
register int i;
/* We must rerun eliminate_regs, in case the elimination
offsets have changed. */
rtx tem = XEXP (eliminate_regs (reg_equiv_memory_loc[regno], 0, NULL_RTX, 0),
0);
rtx tem = XEXP (eliminate_regs (reg_equiv_memory_loc[regno], 0, NULL_RTX), 0);
#if 0 /* We cannot safely reuse a memloc made here;
if the pseudo appears twice, and its mem needs a reload,

View File

@ -145,11 +145,6 @@ extern void clear_secondary_mem PROTO((void));
reload TO. */
extern void transfer_replacements PROTO((int, int));
/* Return 1 if ADDR is a valid memory address for mode MODE,
and check that each pseudo reg has the proper kind of
hard reg. */
extern int strict_memory_address_p PROTO((enum machine_mode, rtx));
/* Like rtx_equal_p except that it allows a REG and a SUBREG to match
if they are the same hard reg, and has special hacks for
autoincrement and autodecrement. */
@ -212,7 +207,7 @@ extern int regno_clobbered_p PROTO((int, rtx));
extern void init_reload PROTO((void));
/* The reload pass itself. */
extern int reload STDIO_PROTO((rtx, int, FILE *));
extern int reload PROTO((rtx, int, FILE *));
/* Mark the slots in regs_ever_live for the hard regs
used by pseudo-reg number REGNO. */
@ -220,7 +215,7 @@ extern void mark_home_live PROTO((int));
/* Scan X and replace any eliminable registers (such as fp) with a
replacement (such as sp), plus an offset. */
extern rtx eliminate_regs PROTO((rtx, enum machine_mode, rtx, int));
extern rtx eliminate_regs PROTO((rtx, enum machine_mode, rtx));
/* Emit code to perform a reload from IN (which may be a reload register) to
OUT (which may also be a reload register). IN or OUT is from operand

View File

@ -980,7 +980,7 @@ reload (first, global, dumpfile)
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
if (reg_renumber[i] < 0 && reg_equiv_memory_loc[i])
{
rtx x = eliminate_regs (reg_equiv_memory_loc[i], 0, NULL_RTX, 0);
rtx x = eliminate_regs (reg_equiv_memory_loc[i], 0, NULL_RTX);
if (strict_memory_address_p (GET_MODE (regno_reg_rtx[i]),
XEXP (x, 0)))
@ -2812,11 +2812,10 @@ static struct rtvec_def *old_asm_operands_vec, *new_asm_operands_vec;
the proper thing. */
rtx
eliminate_regs (x, mem_mode, insn, storing)
eliminate_regs (x, mem_mode, insn)
rtx x;
enum machine_mode mem_mode;
rtx insn;
int storing;
{
enum rtx_code code = GET_CODE (x);
struct elim_table *ep;
@ -2845,7 +2844,7 @@ eliminate_regs (x, mem_mode, insn, storing)
/* This is only for the benefit of the debugging backends, which call
eliminate_regs on DECL_RTL; any ADDRESSOFs in the actual insns are
removed after CSE. */
new = eliminate_regs (XEXP (x, 0), 0, insn, 0);
new = eliminate_regs (XEXP (x, 0), 0, insn);
if (GET_CODE (new) == MEM)
return XEXP (new, 0);
return x;
@ -2881,8 +2880,7 @@ eliminate_regs (x, mem_mode, insn, storing)
elimination) and ignore the fact that this is actually a
reference to the pseudo. Ensure we make a copy of the
address in case it is shared. */
new = eliminate_regs (reg_equiv_memory_loc[regno],
mem_mode, insn, 0);
new = eliminate_regs (reg_equiv_memory_loc[regno], mem_mode, insn);
if (new != reg_equiv_memory_loc[regno])
{
cannot_omit_stores[regno] = 1;
@ -2944,8 +2942,8 @@ eliminate_regs (x, mem_mode, insn, storing)
reload. This is the desired action. */
{
rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn, 0);
rtx new1 = eliminate_regs (XEXP (x, 1), mem_mode, insn, 0);
rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn);
rtx new1 = eliminate_regs (XEXP (x, 1), mem_mode, insn);
if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
{
@ -3016,9 +3014,9 @@ eliminate_regs (x, mem_mode, insn, storing)
case GE: case GT: case GEU: case GTU:
case LE: case LT: case LEU: case LTU:
{
rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn, 0);
rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn);
rtx new1
= XEXP (x, 1) ? eliminate_regs (XEXP (x, 1), mem_mode, insn, 0) : 0;
= XEXP (x, 1) ? eliminate_regs (XEXP (x, 1), mem_mode, insn) : 0;
if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
return gen_rtx (code, GET_MODE (x), new0, new1);
@ -3029,7 +3027,7 @@ eliminate_regs (x, mem_mode, insn, storing)
/* If we have something in XEXP (x, 0), the usual case, eliminate it. */
if (XEXP (x, 0))
{
new = eliminate_regs (XEXP (x, 0), mem_mode, insn, 0);
new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
if (new != XEXP (x, 0))
x = gen_rtx (EXPR_LIST, REG_NOTE_KIND (x), new, XEXP (x, 1));
}
@ -3042,7 +3040,7 @@ eliminate_regs (x, mem_mode, insn, storing)
strictly needed, but it simplifies the code. */
if (XEXP (x, 1))
{
new = eliminate_regs (XEXP (x, 1), mem_mode, insn, 0);
new = eliminate_regs (XEXP (x, 1), mem_mode, insn);
if (new != XEXP (x, 1))
return gen_rtx (GET_CODE (x), GET_MODE (x), XEXP (x, 0), new);
}
@ -3078,7 +3076,7 @@ eliminate_regs (x, mem_mode, insn, storing)
case ABS:
case SQRT:
case FFS:
new = eliminate_regs (XEXP (x, 0), mem_mode, insn, 0);
new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
if (new != XEXP (x, 0))
return gen_rtx (code, GET_MODE (x), new);
return x;
@ -3097,7 +3095,7 @@ eliminate_regs (x, mem_mode, insn, storing)
&& reg_equiv_memory_loc[REGNO (SUBREG_REG (x))] != 0)
{
new = eliminate_regs (reg_equiv_memory_loc[REGNO (SUBREG_REG (x))],
mem_mode, insn, 0);
mem_mode, insn);
/* If we didn't change anything, we must retain the pseudo. */
if (new == reg_equiv_memory_loc[REGNO (SUBREG_REG (x))])
@ -3117,37 +3115,38 @@ eliminate_regs (x, mem_mode, insn, storing)
}
}
else
new = eliminate_regs (SUBREG_REG (x), mem_mode, insn, 0);
new = eliminate_regs (SUBREG_REG (x), mem_mode, insn);
if (new != XEXP (x, 0))
{
int x_size = GET_MODE_SIZE (GET_MODE (x));
int new_size = GET_MODE_SIZE (GET_MODE (new));
/* When asked to spill a partial word subreg, we need to go
ahead and spill the whole thing against the possibility
that we reload the whole reg and find garbage at the top. */
if (storing
&& GET_CODE (new) == MEM
&& x_size < new_size
&& ((x_size + UNITS_PER_WORD-1) / UNITS_PER_WORD
== (new_size + UNITS_PER_WORD-1) / UNITS_PER_WORD))
return new;
else if (GET_CODE (new) == MEM
&& x_size <= new_size
#ifdef LOAD_EXTEND_OP
/* On these machines we will be reloading what is
inside the SUBREG if it originally was a pseudo and
the inner and outer modes are both a word or
smaller. So leave the SUBREG then. */
&& ! (GET_CODE (SUBREG_REG (x)) == REG
&& x_size <= UNITS_PER_WORD
&& new_size <= UNITS_PER_WORD
&& x_size > new_size
&& INTEGRAL_MODE_P (GET_MODE (new))
&& LOAD_EXTEND_OP (GET_MODE (new)) != NIL)
if (GET_CODE (new) == MEM
&& x_size <= new_size
#ifdef WORD_REGISTER_OPERATIONS
/* On these machines, combine can create rtl of the form
(set (subreg:m1 (reg:m2 R) 0) ...)
where m1 < m2, and expects something interesting to
happen to the entire word. Moreover, it will use the
(reg:m2 R) later, expecting all bits to be preserved.
So if the number of words is the same, preserve the
subreg so that push_reloads can see it. */
&& ! ((x_size-1)/UNITS_PER_WORD == (new_size-1)/UNITS_PER_WORD)
#endif
)
#ifdef LOAD_EXTEND_OP
/* On these machines we will be reloading what is
inside the SUBREG if it originally was a pseudo and
the inner and outer modes are both a word or
smaller. So leave the SUBREG then. */
&& ! (GET_CODE (SUBREG_REG (x)) == REG
&& x_size <= UNITS_PER_WORD
&& new_size <= UNITS_PER_WORD
&& x_size > new_size
&& INTEGRAL_MODE_P (GET_MODE (new))
&& LOAD_EXTEND_OP (GET_MODE (new)) != NIL)
#endif
)
{
int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
enum machine_mode mode = GET_MODE (x);
@ -3175,7 +3174,7 @@ eliminate_regs (x, mem_mode, insn, storing)
if (ep->from_rtx == XEXP (x, 0))
ep->can_eliminate = 0;
new = eliminate_regs (XEXP (x, 0), mem_mode, insn, 0);
new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
if (new != XEXP (x, 0))
return gen_rtx (code, GET_MODE (x), new);
return x;
@ -3188,7 +3187,7 @@ eliminate_regs (x, mem_mode, insn, storing)
if (ep->to_rtx == XEXP (x, 0))
ep->can_eliminate = 0;
new = eliminate_regs (XEXP (x, 0), mem_mode, insn, 0);
new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
if (new != XEXP (x, 0))
return gen_rtx (code, GET_MODE (x), new);
return x;
@ -3206,7 +3205,7 @@ eliminate_regs (x, mem_mode, insn, storing)
temp_vec = (rtx *) alloca (XVECLEN (x, 3) * sizeof (rtx));
for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
temp_vec[i] = eliminate_regs (ASM_OPERANDS_INPUT (x, i),
mem_mode, insn, 0);
mem_mode, insn);
for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
if (temp_vec[i] != ASM_OPERANDS_INPUT (x, i))
@ -3277,8 +3276,8 @@ eliminate_regs (x, mem_mode, insn, storing)
/* Now avoid the loop below in this common case. */
{
rtx new0 = eliminate_regs (SET_DEST (x), 0, insn, 1);
rtx new1 = eliminate_regs (SET_SRC (x), 0, insn, 0);
rtx new0 = eliminate_regs (SET_DEST (x), 0, insn);
rtx new1 = eliminate_regs (SET_SRC (x), 0, insn);
/* If SET_DEST changed from a REG to a MEM and INSN is an insn,
write a CLOBBER insn. */
@ -3287,12 +3286,6 @@ eliminate_regs (x, mem_mode, insn, storing)
&& GET_CODE (insn) != INSN_LIST)
emit_insn_after (gen_rtx (CLOBBER, VOIDmode, SET_DEST (x)), insn);
/* If SET_DEST was a partial-word subreg, NEW0 may have been widened
to spill the entire register (see SUBREG case above). If the
widths of SET_DEST and NEW0 no longer match, adjust NEW1. */
if (GET_MODE (SET_DEST (x)) != GET_MODE (new0))
new1 = gen_rtx (SUBREG, GET_MODE (new0), new1, 0);
if (new0 != SET_DEST (x) || new1 != SET_SRC (x))
return gen_rtx (SET, VOIDmode, new0, new1);
}
@ -3304,12 +3297,12 @@ eliminate_regs (x, mem_mode, insn, storing)
eliminate_regs on DECL_RTL; any ADDRESSOFs in the actual insns are
removed after CSE. */
if (GET_CODE (XEXP (x, 0)) == ADDRESSOF)
return eliminate_regs (XEXP (XEXP (x, 0), 0), 0, insn, 0);
return eliminate_regs (XEXP (XEXP (x, 0), 0), 0, insn);
/* Our only special processing is to pass the mode of the MEM to our
recursive call and copy the flags. While we are here, handle this
case more efficiently. */
new = eliminate_regs (XEXP (x, 0), GET_MODE (x), insn, 0);
new = eliminate_regs (XEXP (x, 0), GET_MODE (x), insn);
if (new != XEXP (x, 0))
{
new = gen_rtx (MEM, GET_MODE (x), new);
@ -3332,7 +3325,7 @@ eliminate_regs (x, mem_mode, insn, storing)
{
if (*fmt == 'e')
{
new = eliminate_regs (XEXP (x, i), mem_mode, insn, 0);
new = eliminate_regs (XEXP (x, i), mem_mode, insn);
if (new != XEXP (x, i) && ! copied)
{
rtx new_x = rtx_alloc (code);
@ -3349,7 +3342,7 @@ eliminate_regs (x, mem_mode, insn, storing)
int copied_vec = 0;
for (j = 0; j < XVECLEN (x, i); j++)
{
new = eliminate_regs (XVECEXP (x, i, j), mem_mode, insn, 0);
new = eliminate_regs (XVECEXP (x, i, j), mem_mode, insn);
if (new != XVECEXP (x, i, j) && ! copied_vec)
{
rtvec new_v = gen_rtvec_vv (XVECLEN (x, i),
@ -3527,7 +3520,7 @@ eliminate_regs_in_insn (insn, replace)
but now can do this as a load-address. This saves an insn in this
common case. */
new_body = eliminate_regs (old_body, 0, replace ? insn : NULL_RTX, 0);
new_body = eliminate_regs (old_body, 0, replace ? insn : NULL_RTX);
if (new_body != old_body)
{
/* If we aren't replacing things permanently and we changed something,
@ -3616,7 +3609,7 @@ eliminate_regs_in_insn (insn, replace)
of spill registers to be needed in the final reload pass than in
the pre-passes. */
if (val && REG_NOTES (insn) != 0)
REG_NOTES (insn) = eliminate_regs (REG_NOTES (insn), 0, REG_NOTES (insn), 0);
REG_NOTES (insn) = eliminate_regs (REG_NOTES (insn), 0, REG_NOTES (insn));
if (! replace)
pop_obstacks ();
@ -4090,7 +4083,7 @@ reload_as_needed (first, live_known)
XEXP (XEXP (PATTERN (insn), 0), 0)
= eliminate_regs (XEXP (XEXP (PATTERN (insn), 0), 0),
GET_MODE (XEXP (PATTERN (insn), 0)),
NULL_RTX, 0);
NULL_RTX);
/* If we need to do register elimination processing, do so.
This might delete the insn, in which case we are done. */

View File

@ -789,7 +789,7 @@ sdbout_symbol (decl, local)
if (DECL_RTL (decl) == 0)
return;
DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX, 0);
DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX);
#ifdef LEAF_REG_REMAP
if (leaf_function)
leaf_renumber_regs_insn (DECL_RTL (decl));
@ -1289,8 +1289,8 @@ sdbout_parms (parms)
/* Perform any necessary register eliminations on the parameter's rtl,
so that the debugging output will be accurate. */
DECL_INCOMING_RTL (parms)
= eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX, 0);
DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX, 0);
= eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX);
DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX);
if (PARM_PASSED_IN_MEMORY (parms))
{