mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-18 14:30:42 +08:00
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:
parent
fa1610e95b
commit
55c225655f
146
gcc/reload.c
146
gcc/reload.c
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user