Include expr.h.

(find_reloads_address, find_reloads_address_1): New argument INSN.
(find_reloads_address_1): Reload inside of p{re,ost}_{in,de}c
instead of entire p{re,ost}_{in,de}c where appropriate.

From-SVN: r13706
This commit is contained in:
Richard Kenner 1997-03-15 07:28:39 -05:00
parent fa1610e95b
commit 55c225655f
1 changed files with 94 additions and 52 deletions

View File

@ -99,6 +99,7 @@ a register with any other reload. */
#include "flags.h"
#include "real.h"
#include "output.h"
#include "expr.h"
#ifndef REGISTER_MOVE_COST
#define REGISTER_MOVE_COST(x, y) 2
@ -325,11 +326,11 @@ static int alternative_allows_memconst PROTO((char *, int));
static rtx find_reloads_toplev PROTO((rtx, int, enum reload_type, int, int));
static rtx make_memloc PROTO((rtx, int));
static int find_reloads_address PROTO((enum machine_mode, rtx *, rtx, rtx *,
int, enum reload_type, int));
int, enum reload_type, int, rtx));
static rtx subst_reg_equivs PROTO((rtx));
static rtx subst_indexed_address PROTO((rtx));
static int find_reloads_address_1 PROTO((enum machine_mode, rtx, int, rtx *,
int, enum reload_type,int));
int, enum reload_type,int, rtx));
static void find_reloads_address_part PROTO((rtx, rtx *, enum reg_class,
enum machine_mode, int,
enum reload_type, int));
@ -693,7 +694,7 @@ get_secondary_mem (x, mode, opnum, type)
: RELOAD_OTHER);
find_reloads_address (mode, NULL_PTR, XEXP (loc, 0), &XEXP (loc, 0),
opnum, type, 0);
opnum, type, 0, 0);
}
secondary_memlocs_elim[(int) mode][opnum] = loc;
@ -2538,7 +2539,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
{
find_reloads_address (VOIDmode, NULL_PTR,
recog_operand[i], recog_operand_loc[i],
i, operand_type[i], ind_levels);
i, operand_type[i], ind_levels, insn);
/* If we now have a simple operand where we used to have a
PLUS or MULT, re-recognize and try again. */
@ -2561,7 +2562,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
recog_operand_loc[i],
XEXP (recog_operand[i], 0),
&XEXP (recog_operand[i], 0),
i, address_type[i], ind_levels))
i, address_type[i], ind_levels, insn))
address_reloaded[i] = 1;
substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
}
@ -2629,7 +2630,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
recog_operand_loc[i],
XEXP (recog_operand[i], 0),
&XEXP (recog_operand[i], 0),
i, address_type[i], ind_levels);
i, address_type[i], ind_levels, insn);
substed_operand[i] = recog_operand[i] = *recog_operand_loc[i];
}
}
@ -3950,7 +3951,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
if (insn_operand_address_p[insn_code_number][i])
find_reloads_address (VOIDmode, NULL_PTR,
recog_operand[i], recog_operand_loc[i],
i, RELOAD_FOR_INPUT, ind_levels);
i, RELOAD_FOR_INPUT, ind_levels, insn);
/* In these cases, we can't tell if the operand is an input
or an output, so be conservative. In practice it won't be
@ -3961,7 +3962,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
recog_operand_loc[i],
XEXP (recog_operand[i], 0),
&XEXP (recog_operand[i], 0),
i, RELOAD_OTHER, ind_levels);
i, RELOAD_OTHER, ind_levels, insn);
if (code == SUBREG)
recog_operand[i] = *recog_operand_loc[i]
= find_reloads_toplev (recog_operand[i], i, RELOAD_OTHER,
@ -4067,7 +4068,7 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest)
RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[regno]);
find_reloads_address (GET_MODE (x), NULL_PTR,
XEXP (x, 0),
&XEXP (x, 0), opnum, type, ind_levels);
&XEXP (x, 0), opnum, type, ind_levels, 0);
}
return x;
}
@ -4075,7 +4076,7 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest)
{
rtx tem = x;
find_reloads_address (GET_MODE (x), &tem, XEXP (x, 0), &XEXP (x, 0),
opnum, type, ind_levels);
opnum, type, ind_levels, 0);
return tem;
}
@ -4156,7 +4157,7 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest)
RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[regno]);
find_reloads_address (GET_MODE (x), NULL_PTR,
XEXP (x, 0),
&XEXP (x, 0), opnum, type, ind_levels);
&XEXP (x, 0), opnum, type, ind_levels, 0);
}
}
@ -4216,6 +4217,9 @@ make_memloc (ad, regno)
IND_LEVELS says how many levels of indirect addressing this machine
supports.
INSN, if nonzero, is the insn in which we do the reload. It is used
to determine if we may generate output reloads.
Value is nonzero if this address is reloaded or replaced as a whole.
This is interesting to the caller if the address is an autoincrement.
@ -4226,7 +4230,7 @@ make_memloc (ad, regno)
to a hard register, and frame pointer elimination. */
static int
find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
enum machine_mode mode;
rtx *memrefloc;
rtx ad;
@ -4234,6 +4238,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
int opnum;
enum reload_type type;
int ind_levels;
rtx insn;
{
register int regno;
rtx tem;
@ -4258,7 +4263,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
tem = make_memloc (ad, regno);
find_reloads_address (GET_MODE (tem), NULL_PTR, XEXP (tem, 0),
&XEXP (tem, 0), opnum, ADDR_TYPE (type),
ind_levels);
ind_levels, insn);
push_reload (tem, NULL_RTX, loc, NULL_PTR,
reload_address_base_reg_class,
GET_MODE (ad), VOIDmode, 0, 0,
@ -4334,7 +4339,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
tem = ad;
find_reloads_address (GET_MODE (ad), &tem, XEXP (ad, 0), &XEXP (ad, 0),
opnum, ADDR_TYPE (type),
ind_levels == 0 ? 0 : ind_levels - 1);
ind_levels == 0 ? 0 : ind_levels - 1, insn);
/* If tem was changed, then we must create a new memory reference to
hold it and store it back into memrefloc. */
@ -4456,7 +4461,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
reload_address_base_reg_class,
GET_MODE (ad), opnum, type, ind_levels);
find_reloads_address_1 (mode, XEXP (ad, 1), 1, &XEXP (ad, 1), opnum,
type, 0);
type, 0, insn);
return 1;
}
@ -4481,7 +4486,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
reload_address_base_reg_class,
GET_MODE (ad), opnum, type, ind_levels);
find_reloads_address_1 (mode, XEXP (ad, 0), 1, &XEXP (ad, 0), opnum,
type, 0);
type, 0, insn);
return 1;
}
@ -4528,7 +4533,8 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
return 1;
}
return find_reloads_address_1 (mode, ad, 0, loc, opnum, type, ind_levels);
return find_reloads_address_1 (mode, ad, 0, loc, opnum, type, ind_levels,
insn);
}
/* Find all pseudo regs appearing in AD
@ -4704,6 +4710,9 @@ subst_indexed_address (addr)
IND_LEVELS says how many levels of indirect addressing are
supported at this point in the address.
INSN, if nonzero, is the insn in which we do the reload. It is used
to determine if we may generate output reloads.
We return nonzero if X, as a whole, is reloaded or replaced. */
/* Note that we take shortcuts assuming that no multi-reg machine mode
@ -4713,7 +4722,7 @@ subst_indexed_address (addr)
could have addressing modes that this does not handle right. */
static int
find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels)
find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
enum machine_mode mode;
rtx x;
int context;
@ -4721,6 +4730,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels)
int opnum;
enum reload_type type;
int ind_levels;
rtx insn;
{
register RTX_CODE code = GET_CODE (x);
@ -4757,29 +4767,29 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels)
|| code0 == ZERO_EXTEND || code1 == MEM)
{
find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
type, ind_levels);
type, ind_levels, insn);
find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
type, ind_levels);
type, ind_levels, insn);
}
else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
|| code1 == ZERO_EXTEND || code0 == MEM)
{
find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
type, ind_levels);
type, ind_levels, insn);
find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
type, ind_levels);
type, ind_levels, insn);
}
else if (code0 == CONST_INT || code0 == CONST
|| code0 == SYMBOL_REF || code0 == LABEL_REF)
find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
type, ind_levels);
type, ind_levels, insn);
else if (code1 == CONST_INT || code1 == CONST
|| code1 == SYMBOL_REF || code1 == LABEL_REF)
find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
type, ind_levels);
type, ind_levels, insn);
else if (code0 == REG && code1 == REG)
{
@ -4791,39 +4801,39 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels)
return 0;
else if (REG_MODE_OK_FOR_BASE_P (op1, mode))
find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
type, ind_levels);
type, ind_levels, insn);
else if (REG_MODE_OK_FOR_BASE_P (op0, mode))
find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
type, ind_levels);
type, ind_levels, insn);
else if (REG_OK_FOR_INDEX_P (op1))
find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
type, ind_levels);
type, ind_levels, insn);
else if (REG_OK_FOR_INDEX_P (op0))
find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
type, ind_levels);
type, ind_levels, insn);
else
{
find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
type, ind_levels);
type, ind_levels, insn);
find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
type, ind_levels);
type, ind_levels, insn);
}
}
else if (code0 == REG)
{
find_reloads_address_1 (mode, orig_op0, 1, &XEXP (x, 0), opnum,
type, ind_levels);
type, ind_levels, insn);
find_reloads_address_1 (mode, orig_op1, 0, &XEXP (x, 1), opnum,
type, ind_levels);
type, ind_levels, insn);
}
else if (code1 == REG)
{
find_reloads_address_1 (mode, orig_op1, 1, &XEXP (x, 1), opnum,
type, ind_levels);
type, ind_levels, insn);
find_reloads_address_1 (mode, orig_op0, 0, &XEXP (x, 0), opnum,
type, ind_levels);
type, ind_levels, insn);
}
}
@ -4855,7 +4865,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels)
need two registers. */
find_reloads_address (GET_MODE (tem), 0, XEXP (tem, 0),
&XEXP (tem, 0), opnum, type,
ind_levels);
ind_levels, insn);
/* Put this inside a new increment-expression. */
x = gen_rtx (GET_CODE (x), GET_MODE (x), tem);
/* Proceed to reload that, as if it contained a register. */
@ -4879,18 +4889,50 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels)
: REGNO_MODE_OK_FOR_BASE_P (regno, mode))))
{
register rtx link;
int reloadnum;
int reloadnum
= push_reload (x, NULL_RTX, loc, NULL_PTR,
(context
? reload_address_index_reg_class
: reload_address_base_reg_class),
GET_MODE (x), GET_MODE (x), VOIDmode, 0,
opnum, type);
reload_inc[reloadnum]
= find_inc_amount (PATTERN (this_insn), XEXP (x_orig, 0));
value = 1;
/* If we can output the register afterwards, do so, this
saves the extra update.
We can do so if we have an INSN - i.e. no JUMP_INSN nor
CALL_INSN - and it does not set CC0.
But don't do this if we cannot directly address the
memory location, since this will make it harder to
reuse address reloads, and increses register pressure.
Also don't do this if we can probably update x directly. */
rtx equiv = reg_equiv_mem[regno];
int icode = (int) add_optab->handlers[(int) Pmode].insn_code;
if (insn && GET_CODE (insn) == INSN && equiv
#ifdef HAVE_cc0
&& ! sets_cc0_p (PATTERN (insn))
#endif
&& ! (icode != CODE_FOR_nothing
&& (*insn_operand_predicate[icode][0]) (equiv, Pmode)
&& (*insn_operand_predicate[icode][1]) (equiv, Pmode)))
{
loc = &XEXP (x, 0);
x = XEXP (x, 0);
reloadnum
= push_reload (x, x, loc, loc,
(context
? reload_address_index_reg_class
: reload_address_base_reg_class),
GET_MODE (x), GET_MODE (x), VOIDmode, 0,
opnum, RELOAD_OTHER);
}
else
{
reloadnum
= push_reload (x, NULL_RTX, loc, NULL_PTR,
(context
? reload_address_index_reg_class
: reload_address_base_reg_class),
GET_MODE (x), GET_MODE (x), VOIDmode, 0,
opnum, type);
reload_inc[reloadnum]
= find_inc_amount (PATTERN (this_insn), XEXP (x_orig, 0));
value = 1;
}
#ifdef AUTO_INC_DEC
/* Update the REG_INC notes. */
@ -4926,7 +4968,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels)
need two registers. */
find_reloads_address (GET_MODE (x), &XEXP (x, 0),
XEXP (XEXP (x, 0), 0), &XEXP (XEXP (x, 0), 0),
opnum, type, ind_levels);
opnum, type, ind_levels, insn);
reloadnum = push_reload (x, NULL_RTX, loc, NULL_PTR,
(context
@ -4958,7 +5000,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels)
reload1.c here. */
find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
opnum, ADDR_TYPE (type), ind_levels);
opnum, ADDR_TYPE (type), ind_levels, insn);
push_reload (*loc, NULL_RTX, loc, NULL_PTR,
(context ? reload_address_index_reg_class
: reload_address_base_reg_class),
@ -4996,7 +5038,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels)
{
x = make_memloc (x, regno);
find_reloads_address (GET_MODE (x), 0, XEXP (x, 0), &XEXP (x, 0),
opnum, ADDR_TYPE (type), ind_levels);
opnum, ADDR_TYPE (type), ind_levels, insn);
}
if (reg_renumber[regno] >= 0)
@ -5078,7 +5120,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels)
{
if (fmt[i] == 'e')
find_reloads_address_1 (mode, XEXP (x, i), context, &XEXP (x, i),
opnum, type, ind_levels);
opnum, type, ind_levels, insn);
}
}
@ -5116,7 +5158,7 @@ find_reloads_address_part (x, loc, class, mode, opnum, type, ind_levels)
{
rtx tem = x = force_const_mem (mode, x);
find_reloads_address (mode, &tem, XEXP (tem, 0), &XEXP (tem, 0),
opnum, type, ind_levels);
opnum, type, ind_levels, 0);
}
else if (GET_CODE (x) == PLUS
@ -5128,7 +5170,7 @@ find_reloads_address_part (x, loc, class, mode, opnum, type, ind_levels)
x = gen_rtx (PLUS, GET_MODE (x), XEXP (x, 0), tem);
find_reloads_address (mode, &tem, XEXP (tem, 0), &XEXP (tem, 0),
opnum, type, ind_levels);
opnum, type, ind_levels, 0);
}
push_reload (x, NULL_RTX, loc, NULL_PTR, class,