aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@cygnus.com>1998-03-16 11:56:25 +0000
committerKen Raeburn <raeburn@gcc.gnu.org>1998-03-16 11:56:25 +0000
commitcbd5b9a22dbba1046ca3968919449339ea7265c6 (patch)
tree6f74b0e16a811b7beba5cb97f6b174bc298a2458
parent8b1616ad12f821928f25cee27f3008803d13b0d8 (diff)
downloadgcc-cbd5b9a22dbba1046ca3968919449339ea7265c6.zip
gcc-cbd5b9a22dbba1046ca3968919449339ea7265c6.tar.gz
gcc-cbd5b9a22dbba1046ca3968919449339ea7265c6.tar.bz2
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
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/config/1750a/1750a.h2
-rw-r--r--gcc/config/a29k/a29k.h2
-rw-r--r--gcc/config/alpha/alpha.h2
-rw-r--r--gcc/config/arc/arc.h2
-rw-r--r--gcc/config/arm/arm.h2
-rw-r--r--gcc/config/dsp16xx/dsp16xx.h2
-rw-r--r--gcc/config/i386/i386.h2
-rw-r--r--gcc/config/m32r/m32r.h2
-rw-r--r--gcc/config/m88k/m88k.h2
-rw-r--r--gcc/config/mips/mips.h5
-rw-r--r--gcc/config/rs6000/rs6000.h2
-rw-r--r--gcc/regclass.c60
-rw-r--r--gcc/reload.h11
-rw-r--r--gcc/reload1.c13
-rw-r--r--gcc/tm.texi20
16 files changed, 116 insertions, 32 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 532625a..8f95e87 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/1750a/1750a.h b/gcc/config/1750a/1750a.h
index ad6c4be..6c5e9e3 100644
--- a/gcc/config/1750a/1750a.h
+++ b/gcc/config/1750a/1750a.h
@@ -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. */
diff --git a/gcc/config/a29k/a29k.h b/gcc/config/a29k/a29k.h
index 71c2700..d65beb4 100644
--- a/gcc/config/a29k/a29k.h
+++ b/gcc/config/a29k/a29k.h
@@ -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
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index 3e52db7..be3030e 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -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
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index 3d7f2b2..c4696ea 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -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. */
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 7c28c64..0adf6dc 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -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
diff --git a/gcc/config/dsp16xx/dsp16xx.h b/gcc/config/dsp16xx/dsp16xx.h
index 1c0f4dd..61e6bf8 100644
--- a/gcc/config/dsp16xx/dsp16xx.h
+++ b/gcc/config/dsp16xx/dsp16xx.h
@@ -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)
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 53c08b0..b910e77 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -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. */
diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h
index 79233e5..d438b49 100644
--- a/gcc/config/m32r/m32r.h
+++ b/gcc/config/m32r/m32r.h
@@ -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. */
diff --git a/gcc/config/m88k/m88k.h b/gcc/config/m88k/m88k.h
index e35b87e..f0dac24 100644
--- a/gcc/config/m88k/m88k.h
+++ b/gcc/config/m88k/m88k.h
@@ -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)
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 92368f6..4de5f5c 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -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. */
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 0982a64..cdc4bdc 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -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) \
diff --git a/gcc/regclass.c b/gcc/regclass.c
index 3432c79..4cc02080 100644
--- a/gcc/regclass.c
+++ b/gcc/regclass.c
@@ -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;
diff --git a/gcc/reload.h b/gcc/reload.h
index 1419729..d86542f 100644
--- a/gcc/reload.h
+++ b/gcc/reload.h
@@ -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. */
diff --git a/gcc/reload1.c b/gcc/reload1.c
index f416a87..e843cea 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -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
diff --git a/gcc/tm.texi b/gcc/tm.texi
index 00311bf..d8fb724 100644
--- a/gcc/tm.texi
+++ b/gcc/tm.texi
@@ -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