Change MEMORY_MOVE_COST defs and uses to be able to take register class into account.

Change MEMORY_MOVE_COST defs and uses to be able to take register class into
account.  Change mips def to actually do so, others to just ignore extra args.
Doc changes too.

From-SVN: r18621
This commit is contained in:
Ken Raeburn 1998-03-16 11:56:25 +00:00 committed by Ken Raeburn
parent 8b1616ad12
commit cbd5b9a22d
16 changed files with 116 additions and 32 deletions

View File

@ -1,3 +1,22 @@
Mon Mar 16 12:12:36 1998 Ken Raeburn <raeburn@cygnus.com>
* reload.h (MEMORY_MOVE_COST): Define here if not already defined;
if HAVE_SECONDARY_RELOADS, factor in copying cost.
(memory_move_secondary_cost): Declare.
* regclass.c (MEMORY_MOVE_COST): Don't define default here.
(memory_move_secondary_cost) [HAVE_SECONDARY_RELOADS]: New
function.
(regclass, record_reg_classes, copy_cost, record_address_regs):
Pass register class and direction of move to MEMORY_MOVE_COST.
* reload1.c (MEMORY_MOVE_COST): Don't define default here.
(emit_reload_insns, reload_cse_simplify_set): Pass register class
and direction of move to MEMORY_MOVE_COST.
* 1750a.c, a29k.h, alpha.h, arc.h, arm.h, dsp16xx.h, i386.h,
m32r.h, m88k.h, rs6000.h (MEMORY_MOVE_COST): Add extra ignored
arguments to definition, even in comments.
* mips.h (MEMORY_MOVE_COST): Add extra arguments; add
memory_move_secondary_cost result to cpu-specific cost.
Mon Mar 16 11:16:50 1998 Jim Wilson <wilson@cygnus.com>
* README.gnat: New file.

View File

@ -910,7 +910,7 @@ enum reg_class { NO_REGS, R2, R0_1, INDEX_REGS, BASE_REGS, ALL_REGS, LIM_REG_CLA
#define REGISTER_MOVE_COST(FROM,TO) 2
#define MEMORY_MOVE_COST(M) 4
#define MEMORY_MOVE_COST(M,C,I) 4
/* Tell final.c how to eliminate redundant test instructions. */

View File

@ -681,7 +681,7 @@ extern struct rtx_def *a29k_get_reloaded_address ();
this higher. In addition, we need to keep it more expensive than the
most expensive register-register copy. */
#define MEMORY_MOVE_COST(MODE) 6
#define MEMORY_MOVE_COST(MODE,CLASS,IN) 6
/* A C statement (sans semicolon) to update the integer variable COST
based on the relationship between INSN that is dependent on

View File

@ -789,7 +789,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
On the Alpha, bump this up a bit. */
extern int alpha_memory_latency;
#define MEMORY_MOVE_COST(MODE) (2*alpha_memory_latency)
#define MEMORY_MOVE_COST(MODE,CLASS,IN) (2*alpha_memory_latency)
/* Provide the cost of a branch. Exact meaning under development. */
#define BRANCH_COST 5

View File

@ -1102,7 +1102,7 @@ arc_select_cc_mode (OP, X, Y)
/* Compute the cost of moving data between registers and memory. */
/* Memory is 3 times as expensive as registers.
??? Is that the right way to look at it? */
#define MEMORY_MOVE_COST(MODE) \
#define MEMORY_MOVE_COST(MODE,CLASS,IN) \
(GET_MODE_SIZE (MODE) <= UNITS_PER_WORD ? 6 : 12)
/* The cost of a branch insn. */

View File

@ -1624,7 +1624,7 @@ extern struct rtx_def *legitimize_pic_address ();
return arm_rtx_costs (X, CODE, OUTER_CODE);
/* Moves to and from memory are quite expensive */
#define MEMORY_MOVE_COST(MODE) 10
#define MEMORY_MOVE_COST(MODE,CLASS,IN) 10
/* All address computations that can be done are free, but rtx cost returns
the same for practically all of them. So we weight the different types

View File

@ -1556,7 +1556,7 @@ extern struct dsp16xx_frame_info current_frame_info;
/* A C expression for the cost of moving data of mode MODE between
a register and memory. A value of 2 is the default. */
#define MEMORY_MOVE_COST(MODE) \
#define MEMORY_MOVE_COST(MODE,CLASS,IN_P) \
(GET_MODE_CLASS(MODE) == MODE_INT && MODE == QImode ? 12 \
: 16)

View File

@ -2079,7 +2079,7 @@ while (0)
between two registers, you should define this macro to express the
relative cost. */
/* #define MEMORY_MOVE_COST(M) 2 */
/* #define MEMORY_MOVE_COST(M,C,I) 2 */
/* A C expression for the cost of a branch instruction. A value of 1
is the default; other values are interpreted relative to that. */

View File

@ -1268,7 +1268,7 @@ m32r_select_cc_mode (OP, X, Y)
/* Compute the cost of moving data between registers and memory. */
/* Memory is 3 times as expensive as registers.
??? Is that the right way to look at it? */
#define MEMORY_MOVE_COST(MODE) \
#define MEMORY_MOVE_COST(MODE,CLASS,IN_P) \
(GET_MODE_SIZE (MODE) <= UNITS_PER_WORD ? 6 : 12)
/* The cost of a branch insn. */

View File

@ -1690,7 +1690,7 @@ enum reg_class { NO_REGS, AP_REG, XRF_REGS, GENERAL_REGS, AGRF_REGS,
/* A C expressions returning the cost of moving data of MODE from a register
to or from memory. This is more costly than between registers. */
#define MEMORY_MOVE_COST(MODE) 4
#define MEMORY_MOVE_COST(MODE,CLASS,IN) 4
/* Provide the cost of a branch. Exact meaning under development. */
#define BRANCH_COST (TARGET_88100 ? 1 : 2)

View File

@ -3534,8 +3534,9 @@ while (0)
: 12)
/* ??? Fix this to be right for the R8000. */
#define MEMORY_MOVE_COST(MODE) \
((mips_cpu == PROCESSOR_R4000 || mips_cpu == PROCESSOR_R6000) ? 6 : 4)
#define MEMORY_MOVE_COST(MODE,CLASS,TO_P) \
(((mips_cpu == PROCESSOR_R4000 || mips_cpu == PROCESSOR_R6000) ? 6 : 4) \
+ memory_move_secondary_cost ((MODE), (CLASS), (TO_P)))
/* A C expression for the cost of a branch instruction. A value of
1 is the default; other values are interpreted relative to that. */

View File

@ -800,7 +800,7 @@ extern int rs6000_debug_arg; /* debug argument handling */
On the RS/6000, bump this up a bit. */
#define MEMORY_MOVE_COST(MODE) \
#define MEMORY_MOVE_COST(MODE,CLASS,IN) \
((GET_MODE_CLASS (MODE) == MODE_FLOAT \
&& (rs6000_cpu == PROCESSOR_RIOS1 || rs6000_cpu == PROCESSOR_PPC601) \
? 3 : 2) \

View File

@ -42,10 +42,6 @@ Boston, MA 02111-1307, USA. */
#define REGISTER_MOVE_COST(x, y) 2
#endif
#ifndef MEMORY_MOVE_COST
#define MEMORY_MOVE_COST(x) 4
#endif
/* If we have auto-increment or auto-decrement and we can have secondary
reloads, we are not allowed to use classes requiring secondary
reloads for pseudos auto-incremented since reload can't handle it. */
@ -431,6 +427,50 @@ init_regs ()
init_reg_modes ();
}
#ifdef HAVE_SECONDARY_RELOADS
/* Compute extra cost of moving registers to/from memory due to reloads.
Only needed if secondary reloads are required for memory moves. */
int
memory_move_secondary_cost (mode, class, in)
enum machine_mode mode;
enum reg_class class;
int in;
{
enum reg_class altclass;
int partial_cost = 0;
rtx mem;
/* We need a memory reference to feed to SECONDARY... macros. */
mem = gen_rtx (MEM, mode, stack_pointer_rtx);
if (in)
altclass = SECONDARY_INPUT_RELOAD_CLASS (class, mode, mem);
else
altclass = SECONDARY_OUTPUT_RELOAD_CLASS (class, mode, mem);
if (altclass == NO_REGS)
return 0;
if (in)
partial_cost = REGISTER_MOVE_COST (altclass, class);
else
partial_cost = REGISTER_MOVE_COST (class, altclass);
if (class == altclass)
/* This isn't simply a copy-to-temporary situation. Can't guess
what it is, so MEMORY_MOVE_COST really ought not to be calling
here in that case.
I'm tempted to put in an abort here, but returning this will
probably only give poor estimates, which is what we would've
had before this code anyways. */
return partial_cost;
/* Check if the secondary reload register will also need a
secondary reload. */
return memory_move_secondary_cost (mode, altclass, in) + partial_cost;
}
#endif
/* Return a machine mode that is legitimate for hard reg REGNO and large
enough to save nregs. If we can't find one, return VOIDmode. */
@ -773,7 +813,8 @@ regclass (f, nregs)
&& GET_CODE (XEXP (note, 0)) == MEM)
{
costs[REGNO (SET_DEST (set))].mem_cost
-= (MEMORY_MOVE_COST (GET_MODE (SET_DEST (set)))
-= (MEMORY_MOVE_COST (GET_MODE (SET_DEST (set)),
GENERAL_REGS, 1)
* loop_cost);
record_address_regs (XEXP (SET_SRC (set), 0),
BASE_REG_CLASS, loop_cost * 2);
@ -1290,7 +1331,8 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
a bit cheaper since we won't need an extra insn to
load it. */
pp->mem_cost = MEMORY_MOVE_COST (mode) - allows_mem;
pp->mem_cost = (MEMORY_MOVE_COST (mode, classes[i], 1)
- allows_mem);
/* If we have assigned a class to this register in our
first pass, add a cost to this alternative corresponding
@ -1328,7 +1370,7 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
constant that could be placed into memory. */
else if (CONSTANT_P (op) && allows_mem)
alt_cost += MEMORY_MOVE_COST (mode);
alt_cost += MEMORY_MOVE_COST (mode, classes[i], 1);
else
alt_fail = 1;
}
@ -1447,7 +1489,7 @@ copy_cost (x, mode, class, to_p)
else (constants). */
if (GET_CODE (x) == MEM || class == NO_REGS)
return MEMORY_MOVE_COST (mode);
return MEMORY_MOVE_COST (mode, class, to_p);
else if (GET_CODE (x) == REG)
return move_cost[(int) REGNO_REG_CLASS (REGNO (x))][(int) class];
@ -1613,7 +1655,7 @@ record_address_regs (x, class, scale)
register struct costs *pp = &costs[REGNO (x)];
register int i;
pp->mem_cost += (MEMORY_MOVE_COST (Pmode) * scale) / 2;
pp->mem_cost += (MEMORY_MOVE_COST (Pmode, class, 1) * scale) / 2;
for (i = 0; i < N_REG_CLASSES; i++)
pp->cost[i] += (may_move_cost[i][(int) class] * scale) / 2;

View File

@ -34,6 +34,17 @@ Boston, MA 02111-1307, USA. */
#define HAVE_SECONDARY_RELOADS
#endif
/* If MEMORY_MOVE_COST isn't defined, give it a default here. */
#ifndef MEMORY_MOVE_COST
#ifdef HAVE_SECONDARY_RELOADS
#define MEMORY_MOVE_COST(MODE,CLASS,IN) \
(4 + memory_move_secondary_cost ((MODE), (CLASS), (IN)))
#else
#define MEMORY_MOVE_COST(MODE,CLASS,IN) 4
#endif
#endif
extern int memory_move_secondary_cost PROTO ((enum machine_mode, enum reg_class, int));
/* See reload.c and reload1.c for comments on these variables. */
/* Maximum number of reloads we can need. */

View File

@ -76,10 +76,6 @@ Boston, MA 02111-1307, USA. */
#ifndef REGISTER_MOVE_COST
#define REGISTER_MOVE_COST(x, y) 2
#endif
#ifndef MEMORY_MOVE_COST
#define MEMORY_MOVE_COST(x) 4
#endif
/* During reload_as_needed, element N contains a REG rtx for the hard reg
into which reg N has been reloaded (perhaps for a previous insn). */
@ -6141,7 +6137,8 @@ emit_reload_insns (insn)
&& ((REGNO_REG_CLASS (regno) != reload_reg_class[j]
&& (REGISTER_MOVE_COST (REGNO_REG_CLASS (regno),
reload_reg_class[j])
>= MEMORY_MOVE_COST (mode)))
>= MEMORY_MOVE_COST (mode, REGNO_REG_CLASS (regno),
1)))
#ifdef SECONDARY_INPUT_RELOAD_CLASS
|| (SECONDARY_INPUT_RELOAD_CLASS (reload_reg_class[j],
mode, oldequiv)
@ -8204,13 +8201,15 @@ reload_cse_simplify_set (set, insn)
if (side_effects_p (src) || true_regnum (src) >= 0)
return 0;
dclass = REGNO_REG_CLASS (dreg);
/* If memory loads are cheaper than register copies, don't change
them. */
if (GET_CODE (src) == MEM && MEMORY_MOVE_COST (GET_MODE (src)) < 2)
if (GET_CODE (src) == MEM
&& MEMORY_MOVE_COST (GET_MODE (src), dclass, 1) < 2)
return 0;
dest_mode = GET_MODE (SET_DEST (set));
dclass = REGNO_REG_CLASS (dreg);
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
if (i != dreg

View File

@ -4512,14 +4512,26 @@ allow reload to verify that the constraints are met. You should do this
if the @samp{mov@var{m}} pattern's constraints do not allow such copying.
@findex MEMORY_MOVE_COST
@item MEMORY_MOVE_COST (@var{m})
A C expression for the cost of moving data of mode @var{m} between a
register and memory. A value of 4 is the default; this cost is relative
to those in @code{REGISTER_MOVE_COST}.
@item MEMORY_MOVE_COST (@var{mode}, @var{class}, @var{in})
A C expression for the cost of moving data of mode @var{mode} between a
register of class @var{class} and memory; @var{in} is zero if the value
is to be written to memory, non-zero if it is to be read in. If this
macro is not defined, the default cost is assumed to be 4, plus any costs
that would be incurred copying via a secondary reload register, if
needed. This cost is relative to those in @code{REGISTER_MOVE_COST}.
If moving between registers and memory is more expensive than between
two registers, you should define this macro to express the relative cost.
If a secondary reload register would be required for @var{class}, but the
reload mechanism is more complex than copying via an intermediate, this
macro should be defined to reflect the actual cost of the move.
The function @code{memory_move_secondary_cost}, which is defined if
secondary reloads are needed, will compute the costs due to copying; you
can use this function if you need to take other factors into account as
well, or if the default base value of 4 is not correct for your machine.
@findex BRANCH_COST
@item BRANCH_COST
A C expression for the cost of a branch instruction. A value of 1 is